1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 # This script generates jit/LIROpsGenerated.h (list of LIR instructions)
11 from mozbuild
.preprocessor
import Preprocessor
13 HEADER_TEMPLATE
= """\
14 /* This Source Code Form is subject to the terms of the Mozilla Public
15 * License, v. 2.0. If a copy of the MPL was not distributed with this
16 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
18 #ifndef %(includeguard)s
19 #define %(includeguard)s
21 /* This file is generated by jit/GenerateLIRFiles.py. Do not edit! */
25 #endif // %(includeguard)s
29 def load_yaml(yaml_path
):
30 # First invoke preprocessor.py so that we can use #ifdef JS_SIMULATOR in
33 pp
.context
.update(buildconfig
.defines
["ALLDEFINES"])
34 pp
.out
= six
.StringIO()
35 pp
.do_filter("substitution")
36 pp
.do_include(yaml_path
)
37 contents
= pp
.out
.getvalue()
38 return yaml
.safe_load(contents
)
41 def generate_header(c_out
, includeguard
, contents
):
45 "includeguard": includeguard
,
52 "WordSized": "LAllocation",
53 "BoxedValue": "LBoxAllocation",
54 "Int64": "LInt64Allocation",
60 "BoxedValue": "BOX_PIECES",
61 "Int64": "INT64_PIECES",
65 def gen_helper_template_value(num_regular_allocs
, num_value_allocs
, num_int64_allocs
):
68 template_str
+= str(num_value_allocs
) + " * BOX_PIECES + "
70 template_str
+= str(num_int64_allocs
) + " * INT64_PIECES + "
71 template_str
+= str(num_regular_allocs
)
75 def build_index_def(num_specials_operands
, index_value
, num_reg_operands
, piece
):
76 if num_specials_operands
:
77 return " static const size_t {} = {} + {} * {};\\\n".format(
78 index_value
, num_reg_operands
, piece
, num_specials_operands
81 return " static const size_t {} = {};\\\n".format(
82 index_value
, num_reg_operands
87 name
, result_type
, operands
, arguments
, num_temps
, call_instruction
, mir_op
89 """Generates class definition for a single LIR opcode."""
90 class_name
= "L" + name
94 # Operand index definitions.
96 # Parameters for the class constructor.
97 constructor_params
= []
100 num_value_operands
= 0
101 num_int64_operands
= 0
103 # Get number of LAllocations to use for defining indices.
104 for operand
in operands
:
105 if operands
[operand
] == "WordSized":
106 num_reg_operands
+= 1
109 for operand
in operands
:
110 op_type
= operands
[operand
]
111 op_alloc_type
= operand_types
[op_type
]
112 constructor_params
.append("const " + op_alloc_type
+ "& " + operand
)
113 if op_type
== "WordSized":
114 index_value
= str(current_reg_oper
)
115 current_reg_oper
+= 1
121 + "() { return getOperand("
125 setters
.append(" setOperand(" + index_value
+ ", " + operand
+ ");")
126 elif op_type
== "BoxedValue":
127 index_value
= operand
[0].upper() + operand
[1:] + "Index"
130 num_value_operands
, index_value
, num_reg_operands
, "BOX_PIECES"
133 num_value_operands
+= 1
134 # No getters generated for BoxedValue operands.
136 " setBoxOperand(" + index_value
+ ", " + operand
+ ");"
138 elif op_type
== "Int64":
139 index_value
= operand
[0].upper() + operand
[1:] + "Index"
148 num_int64_operands
+= 1
154 + "() { return getInt64Operand("
159 " setInt64Operand(" + index_value
+ ", " + operand
+ ");"
162 raise Exception("Invalid operand type: " + op_type
)
164 for temp
in range(num_temps
):
165 constructor_params
.append("const LDefinition& temp" + str(temp
))
166 setters
.append(" setTemp(" + str(temp
) + ", temp" + str(temp
) + ");")
168 " const LDefinition* temp"
170 + "() { return getTemp("
174 code
= "class {} : public LInstructionHelper<".format(class_name
)
176 code
+= result_types
[result_type
] + ", "
179 code
+= gen_helper_template_value(
180 num_reg_operands
, num_value_operands
, num_int64_operands
182 code
+= ", {}> {{\\\n".format(num_temps
)
184 for arg_name
in arguments
:
185 arg_type_sig
= arguments
[arg_name
]
186 constructor_params
.append(arg_type_sig
+ " " + arg_name
)
187 code
+= " " + arg_type_sig
+ " " + arg_name
+ "_;\\\n"
188 code
+= " public:\\\n LIR_HEADER({})\\\n".format(name
)
189 code
+= " explicit {}(".format(class_name
)
190 code
+= ", ".join(constructor_params
)
191 code
+= ") : LInstructionHelper(classOpcode)"
193 for arg_name
in arguments
:
194 code
+= ", " + arg_name
+ "_(" + arg_name
+ ")"
197 code
+= "\\\n this->setIsCall();"
199 code
+= "\\\n".join(setters
)
201 code
+= "\\\n".join(getters
)
203 for arg_name
in arguments
:
204 code
+= " " + arguments
[arg_name
] + " " + arg_name
+ "() const { "
205 code
+= "return " + arg_name
+ "_; }\\\n"
208 code
+= "\\\n".join(oper_indices
)
211 code
+= " M{}* mir() const {{ return mir_->to{}(); }};\\\n".format(
215 code
+= " M{}* mir() const {{ return mir_->to{}(); }};\\\n".format(
222 def generate_lir_header(c_out
, yaml_path
):
223 data
= load_yaml(yaml_path
)
225 # LIR_OPCODE_LIST opcode.
228 # Generated LIR op class definitions.
234 gen_boilerplate
= op
.get("gen_boilerplate", True)
235 assert isinstance(gen_boilerplate
, bool)
238 result_type
= op
.get("result_type", None)
239 assert result_type
is None or str
241 assert result_types
[result_type
]
243 operands
= op
.get("operands", None)
244 assert operands
is None or isinstance(operands
, dict)
246 arguments
= op
.get("arguments", None)
247 assert arguments
is None or isinstance(arguments
, dict)
249 num_temps
= op
.get("num_temps", 0)
250 assert num_temps
is None or int
252 gen_boilerplate
= op
.get("gen_boilerplate", True)
253 assert isinstance(gen_boilerplate
, bool)
255 call_instruction
= op
.get("call_instruction", None)
256 assert call_instruction
is None or True
258 mir_op
= op
.get("mir_op", None)
259 assert mir_op
is None or True or str
261 lir_op_classes
.append(
273 ops
.append("_({})".format(name
))
275 contents
= "#define LIR_OPCODE_LIST(_)\\\n"
276 contents
+= "\\\n".join(ops
)
279 contents
+= "#define LIR_OPCODE_CLASS_GENERATED \\\n"
280 contents
+= "\\\n".join(lir_op_classes
)
283 generate_header(c_out
, "jit_LIROpsGenerated_h", contents
)