Skip to content

Commit 8d06d1b

Browse files
committed
Fix decoding for register ops; add test
1 parent a0832d5 commit 8d06d1b

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

Tools/cases_generator/generate_cases.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,11 @@ def __init__(self, inst: parser.InstDef, a: "Analyzer"):
240240
break
241241
self.unmoved_names = frozenset(unmoved_names)
242242
if self.register:
243-
num_regs = len(self.input_effects) + len(self.output_effects)
244-
num_dummies = (num_regs // 2) * 2 + 1 - num_regs
245-
fmt = "I" + "B"*num_regs + "X"*num_dummies
243+
fmt = "I"
244+
for effect in self.input_effects + self.output_effects:
245+
fmt += "X" if effect.name == UNUSED else "B"
246+
if len(fmt) % 2 != 0:
247+
fmt += "X"
246248
else:
247249
if variable_used(inst, "oparg"):
248250
fmt = "IB"
@@ -262,7 +264,7 @@ def __init__(self, inst: parser.InstDef, a: "Analyzer"):
262264
self.instr_fmt = fmt
263265

264266
def analyze_registers(self, a: "Analyzer") -> None:
265-
regs = iter(("REG(oparg1)", "REG(oparg2)", "REG(oparg3)"))
267+
regs = iter(("REG(oparg)", "REG(oparg2)", "REG(oparg3)"))
266268
try:
267269
self.input_registers = [
268270
next(regs) for ieff in self.input_effects if ieff.name != UNUSED

Tools/cases_generator/test_generator.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,3 +512,42 @@ def test_extended_cases():
512512
}
513513
"""
514514
run_cases_test(input, output)
515+
516+
def test_long_register():
517+
input = """
518+
register inst(OP1, (left, right -- result)) {
519+
result = spam(left, right);
520+
}
521+
register inst(OP2, (left, unused -- result)) {
522+
result = spam(left, NULL);
523+
}
524+
"""
525+
output = """
526+
TARGET(OP1) {
527+
// Decode rest of instruction
528+
oparg2 = next_instr[0].opcode;
529+
oparg3 = next_instr[0].oparg;
530+
frame->prev_instr = next_instr++;
531+
into_op1:; // For EXTENDED_ARG_3
532+
PyObject *left = REG(oparg);
533+
PyObject *right = REG(oparg2);
534+
PyObject *result;
535+
result = spam(left, right);
536+
Py_XSETREF(REG(oparg3), result);
537+
DISPATCH();
538+
}
539+
540+
TARGET(OP2) {
541+
// Decode rest of instruction
542+
// (oparg2 is unused)
543+
oparg3 = next_instr[0].oparg;
544+
frame->prev_instr = next_instr++;
545+
into_op2:; // For EXTENDED_ARG_3
546+
PyObject *left = REG(oparg);
547+
PyObject *result;
548+
result = spam(left, NULL);
549+
Py_XSETREF(REG(oparg2), result);
550+
DISPATCH();
551+
}
552+
"""
553+
run_cases_test(input, output)

0 commit comments

Comments
 (0)