Mark Shannon avatar Mark Shannon committed 8461893 Draft

Modify CALL_FUNC*, CALL_METH* and CALL_WRAPPER* to make callable constant not variable

Comments (0)

Files changed (11)

HotPy/gen_format_code.py

     'K', 'kkK', 'r', 'rr', 'rrr', 'E', 'rrK',
     'o', 'oo', 'ro', 'rro', 'rrro', 'oK', 'rK', 'rrk',
     'rKE', 'rKKE', 'roK', 'rroK', 'rok', 'rrkkk',
-    'rE', 'rrE', 'rrrE', 'roE', 'rroE', 'rrroE',
-    'rrrroE', 'rrrrE', 'rokkkE', 'rrok', 'p', 'oKKK',
-    'rpE', 'rpoE', 'rpooE', 'rpoooE', 'rroo', 'roo'
+    'rE', 'rrE', 'rroE', 'rrroE',
+    'rokkkE', 'rrok', 'p', 'oKKK',
+    'rrooE', 'rroooE', 'rroo', 'roo',
+    'oKE', 'roKE', 'rrKE', 'rroKE', 'rrrKE', 'rrrokE'
 ]
 
 def defines(formats, outfile):

Include/optimiser.h

     HotPyContext*(*prepare_call1)(HotPyOptimiser*);
     HotPyContext*(*prepare_call2)(HotPyOptimiser*);
     HotPyContext*(*call_object)(HotPyOptimiser*);
+    HotPyContext*(*call_cmethod)(HotPyOptimiser*, PyObject *, int);
+    HotPyContext*(*call_cfunction)(HotPyOptimiser*, PyObject *, int);
+    HotPyContext*(*call_wrapper)(HotPyOptimiser*, int, PyObject *);
     void (*clear)(HotPyOptimiser*);
     int (*start)(HotPyOptimiser*, HotPyTraceObject*, PyFrameObject*, HotPyContext*, char *reason);
     void (*finish)(HotPyOptimiser*);

Include/register_macros.h

 #define FORMAT_ID_kkK 2
 #define FORMAT_ID_o 3
 #define FORMAT_ID_oK 4
-#define FORMAT_ID_oKKK 5
-#define FORMAT_ID_oo 6
-#define FORMAT_ID_p 7
-#define FORMAT_ID_r 8
-#define FORMAT_ID_rE 9
-#define FORMAT_ID_rK 10
-#define FORMAT_ID_rKE 11
-#define FORMAT_ID_rKKE 12
-#define FORMAT_ID_ro 13
-#define FORMAT_ID_roE 14
+#define FORMAT_ID_oKE 5
+#define FORMAT_ID_oKKK 6
+#define FORMAT_ID_oo 7
+#define FORMAT_ID_p 8
+#define FORMAT_ID_r 9
+#define FORMAT_ID_rE 10
+#define FORMAT_ID_rK 11
+#define FORMAT_ID_rKE 12
+#define FORMAT_ID_rKKE 13
+#define FORMAT_ID_ro 14
 #define FORMAT_ID_roK 15
-#define FORMAT_ID_rok 16
-#define FORMAT_ID_rokkkE 17
-#define FORMAT_ID_roo 18
-#define FORMAT_ID_rpE 19
-#define FORMAT_ID_rpoE 20
-#define FORMAT_ID_rpooE 21
-#define FORMAT_ID_rpoooE 22
-#define FORMAT_ID_rr 23
-#define FORMAT_ID_rrE 24
-#define FORMAT_ID_rrK 25
-#define FORMAT_ID_rrk 26
-#define FORMAT_ID_rrkkk 27
-#define FORMAT_ID_rro 28
-#define FORMAT_ID_rroE 29
-#define FORMAT_ID_rroK 30
-#define FORMAT_ID_rrok 31
-#define FORMAT_ID_rroo 32
-#define FORMAT_ID_rrr 33
-#define FORMAT_ID_rrrE 34
-#define FORMAT_ID_rrro 35
-#define FORMAT_ID_rrroE 36
-#define FORMAT_ID_rrrrE 37
-#define FORMAT_ID_rrrroE 38
+#define FORMAT_ID_roKE 16
+#define FORMAT_ID_rok 17
+#define FORMAT_ID_rokkkE 18
+#define FORMAT_ID_roo 19
+#define FORMAT_ID_rr 20
+#define FORMAT_ID_rrE 21
+#define FORMAT_ID_rrK 22
+#define FORMAT_ID_rrKE 23
+#define FORMAT_ID_rrk 24
+#define FORMAT_ID_rrkkk 25
+#define FORMAT_ID_rro 26
+#define FORMAT_ID_rroE 27
+#define FORMAT_ID_rroK 28
+#define FORMAT_ID_rroKE 29
+#define FORMAT_ID_rrok 30
+#define FORMAT_ID_rroo 31
+#define FORMAT_ID_rrooE 32
+#define FORMAT_ID_rroooE 33
+#define FORMAT_ID_rrr 34
+#define FORMAT_ID_rrrKE 35
+#define FORMAT_ID_rrro 36
+#define FORMAT_ID_rrroE 37
+#define FORMAT_ID_rrrokE 38
 
 #define FORMAT_E \
     int e0; \
     k0 = instruction_word >> 16; \
     assert(consistent_format(next_instr[-1] & 255, "oK"))
 
+#define FORMAT_oKE \
+    int r0, k0, e0; \
+    r0 = (instruction_word >> 8) & 255; \
+    k0 = instruction_word >> 16; \
+    instruction_word = *next_instr++; \
+    e0 = instruction_word & ((1 << 16)-1); \
+    assert(consistent_format(next_instr[-2] & 255, "oKE"))
+
 #define FORMAT_oKKK \
     int r0, k0, k1, k2; \
     r0 = (instruction_word >> 8) & 255; \
     r1 = (instruction_word >> 16) & 255; \
     assert(consistent_format(next_instr[-1] & 255, "ro"))
 
-#define FORMAT_roE \
-    int r0, r1, e0; \
-    r0 = (instruction_word >> 8) & 255; \
-    r1 = (instruction_word >> 16) & 255; \
-    instruction_word = *next_instr++; \
-    e0 = instruction_word & ((1 << 16)-1); \
-    assert(consistent_format(next_instr[-2] & 255, "roE"))
-
 #define FORMAT_roK \
     int r0, r1, k0; \
     r0 = (instruction_word >> 8) & 255; \
     k0 = instruction_word & ((1 << 16)-1); \
     assert(consistent_format(next_instr[-2] & 255, "roK"))
 
+#define FORMAT_roKE \
+    int r0, r1, k0, e0; \
+    r0 = (instruction_word >> 8) & 255; \
+    r1 = (instruction_word >> 16) & 255; \
+    instruction_word = *next_instr++; \
+    k0 = instruction_word & ((1 << 16)-1); \
+    e0 = instruction_word >> 16; \
+    assert(consistent_format(next_instr[-2] & 255, "roKE"))
+
 #define FORMAT_rok \
     int r0, r1, k0; \
     r0 = (instruction_word >> 8) & 255; \
     r2 = (instruction_word >> 24); \
     assert(consistent_format(next_instr[-1] & 255, "roo"))
 
-#define FORMAT_rpE \
-    int r0, r1, e0; \
-    r0 = (instruction_word >> 8) & 255; \
-    r1 = (instruction_word >> 16) & 255; \
-    instruction_word = *next_instr++; \
-    e0 = instruction_word & ((1 << 16)-1); \
-    assert(consistent_format(next_instr[-2] & 255, "rpE"))
-
-#define FORMAT_rpoE \
-    int r0, r1, r2, e0; \
-    r0 = (instruction_word >> 8) & 255; \
-    r1 = (instruction_word >> 16) & 255; \
-    r2 = (instruction_word >> 24); \
-    instruction_word = *next_instr++; \
-    e0 = instruction_word & ((1 << 16)-1); \
-    assert(consistent_format(next_instr[-2] & 255, "rpoE"))
-
-#define FORMAT_rpooE \
-    int r0, r1, r2, r3, e0; \
-    r0 = (instruction_word >> 8) & 255; \
-    r1 = (instruction_word >> 16) & 255; \
-    r2 = (instruction_word >> 24); \
-    instruction_word = *next_instr++; \
-    r3 = instruction_word & 255; \
-    e0 = instruction_word >> 16; \
-    assert(consistent_format(next_instr[-2] & 255, "rpooE"))
-
-#define FORMAT_rpoooE \
-    int r0, r1, r2, r3, r4, e0; \
-    r0 = (instruction_word >> 8) & 255; \
-    r1 = (instruction_word >> 16) & 255; \
-    r2 = (instruction_word >> 24); \
-    instruction_word = *next_instr++; \
-    r3 = instruction_word & 255; \
-    r4 = (instruction_word >> 8) & 255; \
-    e0 = instruction_word >> 16; \
-    assert(consistent_format(next_instr[-2] & 255, "rpoooE"))
-
 #define FORMAT_rr \
     int r0, r1; \
     r0 = (instruction_word >> 8) & 255; \
     k0 = instruction_word & ((1 << 16)-1); \
     assert(consistent_format(next_instr[-2] & 255, "rrK"))
 
+#define FORMAT_rrKE \
+    int r0, r1, k0, e0; \
+    r0 = (instruction_word >> 8) & 255; \
+    r1 = (instruction_word >> 16) & 255; \
+    instruction_word = *next_instr++; \
+    k0 = instruction_word & ((1 << 16)-1); \
+    e0 = instruction_word >> 16; \
+    assert(consistent_format(next_instr[-2] & 255, "rrKE"))
+
 #define FORMAT_rrk \
     int r0, r1, k0; \
     r0 = (instruction_word >> 8) & 255; \
     k0 = instruction_word & ((1 << 16)-1); \
     assert(consistent_format(next_instr[-2] & 255, "rroK"))
 
+#define FORMAT_rroKE \
+    int r0, r1, r2, k0, e0; \
+    r0 = (instruction_word >> 8) & 255; \
+    r1 = (instruction_word >> 16) & 255; \
+    r2 = (instruction_word >> 24); \
+    instruction_word = *next_instr++; \
+    k0 = instruction_word & ((1 << 16)-1); \
+    e0 = instruction_word >> 16; \
+    assert(consistent_format(next_instr[-2] & 255, "rroKE"))
+
 #define FORMAT_rrok \
     int r0, r1, r2, k0; \
     r0 = (instruction_word >> 8) & 255; \
     r3 = instruction_word & 255; \
     assert(consistent_format(next_instr[-2] & 255, "rroo"))
 
+#define FORMAT_rrooE \
+    int r0, r1, r2, r3, e0; \
+    r0 = (instruction_word >> 8) & 255; \
+    r1 = (instruction_word >> 16) & 255; \
+    r2 = (instruction_word >> 24); \
+    instruction_word = *next_instr++; \
+    r3 = instruction_word & 255; \
+    e0 = instruction_word >> 16; \
+    assert(consistent_format(next_instr[-2] & 255, "rrooE"))
+
+#define FORMAT_rroooE \
+    int r0, r1, r2, r3, r4, e0; \
+    r0 = (instruction_word >> 8) & 255; \
+    r1 = (instruction_word >> 16) & 255; \
+    r2 = (instruction_word >> 24); \
+    instruction_word = *next_instr++; \
+    r3 = instruction_word & 255; \
+    r4 = (instruction_word >> 8) & 255; \
+    e0 = instruction_word >> 16; \
+    assert(consistent_format(next_instr[-2] & 255, "rroooE"))
+
 #define FORMAT_rrr \
     int r0, r1, r2; \
     r0 = (instruction_word >> 8) & 255; \
     r2 = (instruction_word >> 24); \
     assert(consistent_format(next_instr[-1] & 255, "rrr"))
 
-#define FORMAT_rrrE \
-    int r0, r1, r2, e0; \
+#define FORMAT_rrrKE \
+    int r0, r1, r2, k0, e0; \
     r0 = (instruction_word >> 8) & 255; \
     r1 = (instruction_word >> 16) & 255; \
     r2 = (instruction_word >> 24); \
     instruction_word = *next_instr++; \
-    e0 = instruction_word & ((1 << 16)-1); \
-    assert(consistent_format(next_instr[-2] & 255, "rrrE"))
+    k0 = instruction_word & ((1 << 16)-1); \
+    e0 = instruction_word >> 16; \
+    assert(consistent_format(next_instr[-2] & 255, "rrrKE"))
 
 #define FORMAT_rrro \
     int r0, r1, r2, r3; \
     e0 = instruction_word >> 16; \
     assert(consistent_format(next_instr[-2] & 255, "rrroE"))
 
-#define FORMAT_rrrrE \
-    int r0, r1, r2, r3, e0; \
+#define FORMAT_rrrokE \
+    int r0, r1, r2, r3, k0, e0; \
     r0 = (instruction_word >> 8) & 255; \
     r1 = (instruction_word >> 16) & 255; \
     r2 = (instruction_word >> 24); \
     instruction_word = *next_instr++; \
     r3 = instruction_word & 255; \
+    k0 = (instruction_word >> 8) & 255; \
     e0 = instruction_word >> 16; \
-    assert(consistent_format(next_instr[-2] & 255, "rrrrE"))
+    assert(consistent_format(next_instr[-2] & 255, "rrrokE"))
 
-#define FORMAT_rrrroE \
-    int r0, r1, r2, r3, r4, e0; \
-    r0 = (instruction_word >> 8) & 255; \
-    r1 = (instruction_word >> 16) & 255; \
-    r2 = (instruction_word >> 24); \
-    instruction_word = *next_instr++; \
-    r3 = instruction_word & 255; \
-    r4 = (instruction_word >> 8) & 255; \
-    e0 = instruction_word >> 16; \
-    assert(consistent_format(next_instr[-2] & 255, "rrrroE"))
-

Include/register_write_functions.h

 }
 
 static void
+write_oKE(HotPyOptimiser *x, int op, int k0, int exit)
+{
+    int out0;
+    assert(k0 >= 0);
+    assert(exit >= 0);
+    flush_stack(x);
+    out0 = choose_register(x);
+    assert(consistent_format(op, "oKE"));
+    write_word_112(x, op, out0, k0);
+    write_word_22(x, exit, 0);
+    push_register(x, out0);
+}
+
+static void
 write_oKKK(HotPyOptimiser *x, int op, int k0, int k1, int k2)
 {
     int out0;
 }
 
 static void
-write_roE(HotPyOptimiser *x, int op, int exit)
-{
-    int r0 = pop_as_register(x, 0);
-    int out0;
-    assert(exit >= 0);
-    flush_stack(x);
-    out0 = choose_register(x);
-    assert(consistent_format(op, "roE"));
-    write_word_1111(x, op, r0, out0, 0);
-    write_word_22(x, exit, 0);
-    push_register(x, out0);
-}
-
-static void
 write_roK(HotPyOptimiser *x, int op, int k0)
 {
     int r0 = pop_as_register(x, 0);
 }
 
 static void
+write_roKE(HotPyOptimiser *x, int op, int k0, int exit)
+{
+    int r0 = pop_as_register(x, 0);
+    int out0;
+    assert(k0 >= 0);
+    assert(exit >= 0);
+    flush_stack(x);
+    out0 = choose_register(x);
+    assert(consistent_format(op, "roKE"));
+    write_word_1111(x, op, r0, out0, 0);
+    write_word_22(x, k0, exit);
+    push_register(x, out0);
+}
+
+static void
 write_rok(HotPyOptimiser *x, int op, int k0)
 {
     int r0 = pop_as_register(x, 0);
 }
 
 static void
-write_rpE(HotPyOptimiser *x, int op, int exit)
-{
-    int r1 = pop_as_register(x, 1);
-    int r0 = peek_as_register(x, 0);
-    assert(exit >= 0);
-    flush_stack(x);
-    assert(consistent_format(op, "rpE"));
-    write_word_1111(x, op, r0, r1, 0);
-    write_word_22(x, exit, 0);
-}
-
-static void
-write_rpoE(HotPyOptimiser *x, int op, int exit)
-{
-    int r1 = pop_as_register(x, 1);
-    int r0 = peek_as_register(x, 0);
-    int out0;
-    assert(exit >= 0);
-    flush_stack(x);
-    out0 = choose_register(x);
-    assert(consistent_format(op, "rpoE"));
-    write_word_1111(x, op, r0, r1, out0);
-    write_word_22(x, exit, 0);
-    push_register(x, out0);
-}
-
-static void
-write_rpooE(HotPyOptimiser *x, int op, int exit)
-{
-    int r1 = pop_as_register(x, 1);
-    int r0 = peek_as_register(x, 0);
-    int out0;
-    int out1;
-    assert(exit >= 0);
-    flush_stack(x);
-    out0 = choose_register(x);
-    out1 = choose_register(x);
-    assert(consistent_format(op, "rpooE"));
-    write_word_1111(x, op, r0, r1, out0);
-    write_word_112(x, out1, 0, exit);
-    push_register(x, out0);
-    push_register(x, out1);
-}
-
-static void
-write_rpoooE(HotPyOptimiser *x, int op, int exit)
-{
-    int r1 = pop_as_register(x, 1);
-    int r0 = peek_as_register(x, 0);
-    int out0;
-    int out1;
-    int out2;
-    assert(exit >= 0);
-    flush_stack(x);
-    out0 = choose_register(x);
-    out1 = choose_register(x);
-    out2 = choose_register(x);
-    assert(consistent_format(op, "rpoooE"));
-    write_word_1111(x, op, r0, r1, out0);
-    write_word_112(x, out1, out2, exit);
-    push_register(x, out0);
-    push_register(x, out1);
-    push_register(x, out2);
-}
-
-static void
 write_rr(HotPyOptimiser *x, int op)
 {
     int r1 = pop_as_register(x, 1);
 }
 
 static void
+write_rrKE(HotPyOptimiser *x, int op, int k0, int exit)
+{
+    int r1 = pop_as_register(x, 1);
+    int r0 = pop_as_register(x, 0);
+    assert(k0 >= 0);
+    assert(exit >= 0);
+    flush_stack(x);
+    assert(consistent_format(op, "rrKE"));
+    write_word_1111(x, op, r0, r1, 0);
+    write_word_22(x, k0, exit);
+}
+
+static void
 write_rrk(HotPyOptimiser *x, int op, int k0)
 {
     int r1 = pop_as_register(x, 1);
 }
 
 static void
+write_rroKE(HotPyOptimiser *x, int op, int k0, int exit)
+{
+    int r1 = pop_as_register(x, 1);
+    int r0 = pop_as_register(x, 0);
+    int out0;
+    assert(k0 >= 0);
+    assert(exit >= 0);
+    flush_stack(x);
+    out0 = choose_register(x);
+    assert(consistent_format(op, "rroKE"));
+    write_word_1111(x, op, r0, r1, out0);
+    write_word_22(x, k0, exit);
+    push_register(x, out0);
+}
+
+static void
 write_rrok(HotPyOptimiser *x, int op, int k0)
 {
     int r1 = pop_as_register(x, 1);
 }
 
 static void
+write_rrooE(HotPyOptimiser *x, int op, int exit)
+{
+    int r1 = pop_as_register(x, 1);
+    int r0 = pop_as_register(x, 0);
+    int out0;
+    int out1;
+    assert(exit >= 0);
+    flush_stack(x);
+    out0 = choose_register(x);
+    out1 = choose_register(x);
+    assert(consistent_format(op, "rrooE"));
+    write_word_1111(x, op, r0, r1, out0);
+    write_word_112(x, out1, 0, exit);
+    push_register(x, out0);
+    push_register(x, out1);
+}
+
+static void
+write_rroooE(HotPyOptimiser *x, int op, int exit)
+{
+    int r1 = pop_as_register(x, 1);
+    int r0 = pop_as_register(x, 0);
+    int out0;
+    int out1;
+    int out2;
+    assert(exit >= 0);
+    flush_stack(x);
+    out0 = choose_register(x);
+    out1 = choose_register(x);
+    out2 = choose_register(x);
+    assert(consistent_format(op, "rroooE"));
+    write_word_1111(x, op, r0, r1, out0);
+    write_word_112(x, out1, out2, exit);
+    push_register(x, out0);
+    push_register(x, out1);
+    push_register(x, out2);
+}
+
+static void
 write_rrr(HotPyOptimiser *x, int op)
 {
     int r2 = pop_as_register(x, 2);
 }
 
 static void
-write_rrrE(HotPyOptimiser *x, int op, int exit)
+write_rrrKE(HotPyOptimiser *x, int op, int k0, int exit)
 {
     int r2 = pop_as_register(x, 2);
     int r1 = pop_as_register(x, 1);
     int r0 = pop_as_register(x, 0);
+    assert(k0 >= 0);
     assert(exit >= 0);
     flush_stack(x);
-    assert(consistent_format(op, "rrrE"));
+    assert(consistent_format(op, "rrrKE"));
     write_word_1111(x, op, r0, r1, r2);
-    write_word_22(x, exit, 0);
+    write_word_22(x, k0, exit);
 }
 
 static void
 }
 
 static void
-write_rrrrE(HotPyOptimiser *x, int op, int exit)
+write_rrrokE(HotPyOptimiser *x, int op, int k0, int exit)
 {
-    int r3 = pop_as_register(x, 3);
-    int r2 = pop_as_register(x, 2);
-    int r1 = pop_as_register(x, 1);
-    int r0 = pop_as_register(x, 0);
-    assert(exit >= 0);
-    flush_stack(x);
-    assert(consistent_format(op, "rrrrE"));
-    write_word_1111(x, op, r0, r1, r2);
-    write_word_112(x, r3, 0, exit);
-}
-
-static void
-write_rrrroE(HotPyOptimiser *x, int op, int exit)
-{
-    int r3 = pop_as_register(x, 3);
     int r2 = pop_as_register(x, 2);
     int r1 = pop_as_register(x, 1);
     int r0 = pop_as_register(x, 0);
     int out0;
+    assert(k0 >= 0);
     assert(exit >= 0);
     flush_stack(x);
     out0 = choose_register(x);
-    assert(consistent_format(op, "rrrroE"));
+    assert(consistent_format(op, "rrrokE"));
     write_word_1111(x, op, r0, r1, r2);
-    write_word_112(x, r3, out0, exit);
+    write_word_112(x, out0, k0, exit);
     push_register(x, out0);
 }
 
 }
 
 void
+print_oKE(FILE* out, uint32_t **instr_ptr)
+{
+    uint32_t *next_instr = *instr_ptr;
+    uint32_t instruction_word = *next_instr++;
+    int op = instruction_word & 255;
+    FORMAT_oKE;
+    *instr_ptr = next_instr;
+    fprintf(out, "%s o%d K%d exit%d\n", _HotPy_Instruction_Names[op], r0, k0, e0);
+}
+
+void
 print_oKKK(FILE* out, uint32_t **instr_ptr)
 {
     uint32_t *next_instr = *instr_ptr;
 }
 
 void
-print_roE(FILE* out, uint32_t **instr_ptr)
-{
-    uint32_t *next_instr = *instr_ptr;
-    uint32_t instruction_word = *next_instr++;
-    int op = instruction_word & 255;
-    FORMAT_roE;
-    *instr_ptr = next_instr;
-    fprintf(out, "%s r%d o%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, e0);
-}
-
-void
 print_roK(FILE* out, uint32_t **instr_ptr)
 {
     uint32_t *next_instr = *instr_ptr;
 }
 
 void
+print_roKE(FILE* out, uint32_t **instr_ptr)
+{
+    uint32_t *next_instr = *instr_ptr;
+    uint32_t instruction_word = *next_instr++;
+    int op = instruction_word & 255;
+    FORMAT_roKE;
+    *instr_ptr = next_instr;
+    fprintf(out, "%s r%d o%d K%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, k0, e0);
+}
+
+void
 print_rok(FILE* out, uint32_t **instr_ptr)
 {
     uint32_t *next_instr = *instr_ptr;
 }
 
 void
-print_rpE(FILE* out, uint32_t **instr_ptr)
-{
-    uint32_t *next_instr = *instr_ptr;
-    uint32_t instruction_word = *next_instr++;
-    int op = instruction_word & 255;
-    FORMAT_rpE;
-    *instr_ptr = next_instr;
-    fprintf(out, "%s r%d p%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, e0);
-}
-
-void
-print_rpoE(FILE* out, uint32_t **instr_ptr)
-{
-    uint32_t *next_instr = *instr_ptr;
-    uint32_t instruction_word = *next_instr++;
-    int op = instruction_word & 255;
-    FORMAT_rpoE;
-    *instr_ptr = next_instr;
-    fprintf(out, "%s r%d p%d o%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, r2, e0);
-}
-
-void
-print_rpooE(FILE* out, uint32_t **instr_ptr)
-{
-    uint32_t *next_instr = *instr_ptr;
-    uint32_t instruction_word = *next_instr++;
-    int op = instruction_word & 255;
-    FORMAT_rpooE;
-    *instr_ptr = next_instr;
-    fprintf(out, "%s r%d p%d o%d o%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, r2, r3, e0);
-}
-
-void
-print_rpoooE(FILE* out, uint32_t **instr_ptr)
-{
-    uint32_t *next_instr = *instr_ptr;
-    uint32_t instruction_word = *next_instr++;
-    int op = instruction_word & 255;
-    FORMAT_rpoooE;
-    *instr_ptr = next_instr;
-    fprintf(out, "%s r%d p%d o%d o%d o%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, r2, r3, r4, e0);
-}
-
-void
 print_rr(FILE* out, uint32_t **instr_ptr)
 {
     uint32_t *next_instr = *instr_ptr;
 }
 
 void
+print_rrKE(FILE* out, uint32_t **instr_ptr)
+{
+    uint32_t *next_instr = *instr_ptr;
+    uint32_t instruction_word = *next_instr++;
+    int op = instruction_word & 255;
+    FORMAT_rrKE;
+    *instr_ptr = next_instr;
+    fprintf(out, "%s r%d r%d K%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, k0, e0);
+}
+
+void
 print_rrk(FILE* out, uint32_t **instr_ptr)
 {
     uint32_t *next_instr = *instr_ptr;
 }
 
 void
+print_rroKE(FILE* out, uint32_t **instr_ptr)
+{
+    uint32_t *next_instr = *instr_ptr;
+    uint32_t instruction_word = *next_instr++;
+    int op = instruction_word & 255;
+    FORMAT_rroKE;
+    *instr_ptr = next_instr;
+    fprintf(out, "%s r%d r%d o%d K%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, r2, k0, e0);
+}
+
+void
 print_rrok(FILE* out, uint32_t **instr_ptr)
 {
     uint32_t *next_instr = *instr_ptr;
 }
 
 void
+print_rrooE(FILE* out, uint32_t **instr_ptr)
+{
+    uint32_t *next_instr = *instr_ptr;
+    uint32_t instruction_word = *next_instr++;
+    int op = instruction_word & 255;
+    FORMAT_rrooE;
+    *instr_ptr = next_instr;
+    fprintf(out, "%s r%d r%d o%d o%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, r2, r3, e0);
+}
+
+void
+print_rroooE(FILE* out, uint32_t **instr_ptr)
+{
+    uint32_t *next_instr = *instr_ptr;
+    uint32_t instruction_word = *next_instr++;
+    int op = instruction_word & 255;
+    FORMAT_rroooE;
+    *instr_ptr = next_instr;
+    fprintf(out, "%s r%d r%d o%d o%d o%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, r2, r3, r4, e0);
+}
+
+void
 print_rrr(FILE* out, uint32_t **instr_ptr)
 {
     uint32_t *next_instr = *instr_ptr;
 }
 
 void
-print_rrrE(FILE* out, uint32_t **instr_ptr)
+print_rrrKE(FILE* out, uint32_t **instr_ptr)
 {
     uint32_t *next_instr = *instr_ptr;
     uint32_t instruction_word = *next_instr++;
     int op = instruction_word & 255;
-    FORMAT_rrrE;
+    FORMAT_rrrKE;
     *instr_ptr = next_instr;
-    fprintf(out, "%s r%d r%d r%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, r2, e0);
+    fprintf(out, "%s r%d r%d r%d K%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, r2, k0, e0);
 }
 
 void
 }
 
 void
-print_rrrrE(FILE* out, uint32_t **instr_ptr)
+print_rrrokE(FILE* out, uint32_t **instr_ptr)
 {
     uint32_t *next_instr = *instr_ptr;
     uint32_t instruction_word = *next_instr++;
     int op = instruction_word & 255;
-    FORMAT_rrrrE;
+    FORMAT_rrrokE;
     *instr_ptr = next_instr;
-    fprintf(out, "%s r%d r%d r%d r%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, r2, r3, e0);
-}
-
-void
-print_rrrroE(FILE* out, uint32_t **instr_ptr)
-{
-    uint32_t *next_instr = *instr_ptr;
-    uint32_t instruction_word = *next_instr++;
-    int op = instruction_word & 255;
-    FORMAT_rrrroE;
-    *instr_ptr = next_instr;
-    fprintf(out, "%s r%d r%d r%d r%d o%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, r2, r3, r4, e0);
+    fprintf(out, "%s r%d r%d r%d o%d k%d exit%d\n", _HotPy_Instruction_Names[op], r0, r1, r2, r3, k0, e0);
 }
 
 static uint32_t *
 }
 
 static uint32_t *
+defuses_for_oKE(uint32_t *next_instr, int *defs, int *uses)
+{
+    uint32_t instruction_word = *next_instr++;
+    FORMAT_oKE;
+    *defs++ = r0;
+    (void)k0;
+    (void)e0;
+    *defs++ = -1;
+    *uses++ = -1;
+    return next_instr;
+}
+
+static uint32_t *
 defuses_for_oKKK(uint32_t *next_instr, int *defs, int *uses)
 {
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
-defuses_for_roE(uint32_t *next_instr, int *defs, int *uses)
-{
-    uint32_t instruction_word = *next_instr++;
-    FORMAT_roE;
-    *uses++ = r0;
-    *defs++ = r1;
-    (void)e0;
-    *defs++ = -1;
-    *uses++ = -1;
-    return next_instr;
-}
-
-static uint32_t *
 defuses_for_roK(uint32_t *next_instr, int *defs, int *uses)
 {
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
+defuses_for_roKE(uint32_t *next_instr, int *defs, int *uses)
+{
+    uint32_t instruction_word = *next_instr++;
+    FORMAT_roKE;
+    *uses++ = r0;
+    *defs++ = r1;
+    (void)k0;
+    (void)e0;
+    *defs++ = -1;
+    *uses++ = -1;
+    return next_instr;
+}
+
+static uint32_t *
 defuses_for_rok(uint32_t *next_instr, int *defs, int *uses)
 {
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
-defuses_for_rpE(uint32_t *next_instr, int *defs, int *uses)
-{
-    uint32_t instruction_word = *next_instr++;
-    FORMAT_rpE;
-    *uses++ = r0;
-    *uses++ = r1;
-    (void)e0;
-    *defs++ = -1;
-    *uses++ = -1;
-    return next_instr;
-}
-
-static uint32_t *
-defuses_for_rpoE(uint32_t *next_instr, int *defs, int *uses)
-{
-    uint32_t instruction_word = *next_instr++;
-    FORMAT_rpoE;
-    *uses++ = r0;
-    *uses++ = r1;
-    *defs++ = r2;
-    (void)e0;
-    *defs++ = -1;
-    *uses++ = -1;
-    return next_instr;
-}
-
-static uint32_t *
-defuses_for_rpooE(uint32_t *next_instr, int *defs, int *uses)
-{
-    uint32_t instruction_word = *next_instr++;
-    FORMAT_rpooE;
-    *uses++ = r0;
-    *uses++ = r1;
-    *defs++ = r2;
-    *defs++ = r3;
-    (void)e0;
-    *defs++ = -1;
-    *uses++ = -1;
-    return next_instr;
-}
-
-static uint32_t *
-defuses_for_rpoooE(uint32_t *next_instr, int *defs, int *uses)
-{
-    uint32_t instruction_word = *next_instr++;
-    FORMAT_rpoooE;
-    *uses++ = r0;
-    *uses++ = r1;
-    *defs++ = r2;
-    *defs++ = r3;
-    *defs++ = r4;
-    (void)e0;
-    *defs++ = -1;
-    *uses++ = -1;
-    return next_instr;
-}
-
-static uint32_t *
 defuses_for_rr(uint32_t *next_instr, int *defs, int *uses)
 {
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
+defuses_for_rrKE(uint32_t *next_instr, int *defs, int *uses)
+{
+    uint32_t instruction_word = *next_instr++;
+    FORMAT_rrKE;
+    *uses++ = r0;
+    *uses++ = r1;
+    (void)k0;
+    (void)e0;
+    *defs++ = -1;
+    *uses++ = -1;
+    return next_instr;
+}
+
+static uint32_t *
 defuses_for_rrk(uint32_t *next_instr, int *defs, int *uses)
 {
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
+defuses_for_rroKE(uint32_t *next_instr, int *defs, int *uses)
+{
+    uint32_t instruction_word = *next_instr++;
+    FORMAT_rroKE;
+    *uses++ = r0;
+    *uses++ = r1;
+    *defs++ = r2;
+    (void)k0;
+    (void)e0;
+    *defs++ = -1;
+    *uses++ = -1;
+    return next_instr;
+}
+
+static uint32_t *
 defuses_for_rrok(uint32_t *next_instr, int *defs, int *uses)
 {
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
+defuses_for_rrooE(uint32_t *next_instr, int *defs, int *uses)
+{
+    uint32_t instruction_word = *next_instr++;
+    FORMAT_rrooE;
+    *uses++ = r0;
+    *uses++ = r1;
+    *defs++ = r2;
+    *defs++ = r3;
+    (void)e0;
+    *defs++ = -1;
+    *uses++ = -1;
+    return next_instr;
+}
+
+static uint32_t *
+defuses_for_rroooE(uint32_t *next_instr, int *defs, int *uses)
+{
+    uint32_t instruction_word = *next_instr++;
+    FORMAT_rroooE;
+    *uses++ = r0;
+    *uses++ = r1;
+    *defs++ = r2;
+    *defs++ = r3;
+    *defs++ = r4;
+    (void)e0;
+    *defs++ = -1;
+    *uses++ = -1;
+    return next_instr;
+}
+
+static uint32_t *
 defuses_for_rrr(uint32_t *next_instr, int *defs, int *uses)
 {
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
-defuses_for_rrrE(uint32_t *next_instr, int *defs, int *uses)
+defuses_for_rrrKE(uint32_t *next_instr, int *defs, int *uses)
 {
     uint32_t instruction_word = *next_instr++;
-    FORMAT_rrrE;
+    FORMAT_rrrKE;
     *uses++ = r0;
     *uses++ = r1;
     *uses++ = r2;
+    (void)k0;
     (void)e0;
     *defs++ = -1;
     *uses++ = -1;
 }
 
 static uint32_t *
-defuses_for_rrrrE(uint32_t *next_instr, int *defs, int *uses)
+defuses_for_rrrokE(uint32_t *next_instr, int *defs, int *uses)
 {
     uint32_t instruction_word = *next_instr++;
-    FORMAT_rrrrE;
+    FORMAT_rrrokE;
     *uses++ = r0;
     *uses++ = r1;
     *uses++ = r2;
-    *uses++ = r3;
-    (void)e0;
-    *defs++ = -1;
-    *uses++ = -1;
-    return next_instr;
-}
-
-static uint32_t *
-defuses_for_rrrroE(uint32_t *next_instr, int *defs, int *uses)
-{
-    uint32_t instruction_word = *next_instr++;
-    FORMAT_rrrroE;
-    *uses++ = r0;
-    *uses++ = r1;
-    *uses++ = r2;
-    *uses++ = r3;
-    *defs++ = r4;
+    *defs++ = r3;
+    (void)k0;
     (void)e0;
     *defs++ = -1;
     *uses++ = -1;
 }
 
 static uint32_t *
+relabel_uses_oKE(uint32_t *next_instr, unsigned char *relabel_table)
+{
+    uint32_t instruction_word = *next_instr++;
+    (void)instruction_word; /* Stop compiler complaining */
+    next_instr[-1] = instruction_word;
+    instruction_word = *next_instr++;
+    next_instr[-1] = instruction_word;
+    return next_instr;
+}
+
+static uint32_t *
 relabel_uses_oKKK(uint32_t *next_instr, unsigned char *relabel_table)
 {
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
-relabel_uses_roE(uint32_t *next_instr, unsigned char *relabel_table)
+relabel_uses_roK(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
-relabel_uses_roK(uint32_t *next_instr, unsigned char *relabel_table)
+relabel_uses_roKE(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
-relabel_uses_rpE(uint32_t *next_instr, unsigned char *relabel_table)
-{
-    int reg;
-    uint32_t instruction_word = *next_instr++;
-    (void)instruction_word; /* Stop compiler complaining */
-    reg = (instruction_word >> 8) & 255; \
-    instruction_word = (instruction_word & 0xffff00ff) | (relabel_table[reg] << 8);
-    reg = (instruction_word >> 16) & 255; \
-    instruction_word = (instruction_word & 0xff00ffff) | (relabel_table[reg] << 16);
-    next_instr[-1] = instruction_word;
-    instruction_word = *next_instr++;
-    next_instr[-1] = instruction_word;
-    return next_instr;
-}
-
-static uint32_t *
-relabel_uses_rpoE(uint32_t *next_instr, unsigned char *relabel_table)
-{
-    int reg;
-    uint32_t instruction_word = *next_instr++;
-    (void)instruction_word; /* Stop compiler complaining */
-    reg = (instruction_word >> 8) & 255; \
-    instruction_word = (instruction_word & 0xffff00ff) | (relabel_table[reg] << 8);
-    reg = (instruction_word >> 16) & 255; \
-    instruction_word = (instruction_word & 0xff00ffff) | (relabel_table[reg] << 16);
-    next_instr[-1] = instruction_word;
-    instruction_word = *next_instr++;
-    next_instr[-1] = instruction_word;
-    return next_instr;
-}
-
-static uint32_t *
-relabel_uses_rpooE(uint32_t *next_instr, unsigned char *relabel_table)
-{
-    int reg;
-    uint32_t instruction_word = *next_instr++;
-    (void)instruction_word; /* Stop compiler complaining */
-    reg = (instruction_word >> 8) & 255; \
-    instruction_word = (instruction_word & 0xffff00ff) | (relabel_table[reg] << 8);
-    reg = (instruction_word >> 16) & 255; \
-    instruction_word = (instruction_word & 0xff00ffff) | (relabel_table[reg] << 16);
-    next_instr[-1] = instruction_word;
-    instruction_word = *next_instr++;
-    next_instr[-1] = instruction_word;
-    return next_instr;
-}
-
-static uint32_t *
-relabel_uses_rpoooE(uint32_t *next_instr, unsigned char *relabel_table)
-{
-    int reg;
-    uint32_t instruction_word = *next_instr++;
-    (void)instruction_word; /* Stop compiler complaining */
-    reg = (instruction_word >> 8) & 255; \
-    instruction_word = (instruction_word & 0xffff00ff) | (relabel_table[reg] << 8);
-    reg = (instruction_word >> 16) & 255; \
-    instruction_word = (instruction_word & 0xff00ffff) | (relabel_table[reg] << 16);
-    next_instr[-1] = instruction_word;
-    instruction_word = *next_instr++;
-    next_instr[-1] = instruction_word;
-    return next_instr;
-}
-
-static uint32_t *
 relabel_uses_rr(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
 }
 
 static uint32_t *
+relabel_uses_rrKE(uint32_t *next_instr, unsigned char *relabel_table)
+{
+    int reg;
+    uint32_t instruction_word = *next_instr++;
+    (void)instruction_word; /* Stop compiler complaining */
+    reg = (instruction_word >> 8) & 255; \
+    instruction_word = (instruction_word & 0xffff00ff) | (relabel_table[reg] << 8);
+    reg = (instruction_word >> 16) & 255; \
+    instruction_word = (instruction_word & 0xff00ffff) | (relabel_table[reg] << 16);
+    next_instr[-1] = instruction_word;
+    instruction_word = *next_instr++;
+    next_instr[-1] = instruction_word;
+    return next_instr;
+}
+
+static uint32_t *
 relabel_uses_rrk(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
 }
 
 static uint32_t *
+relabel_uses_rroKE(uint32_t *next_instr, unsigned char *relabel_table)
+{
+    int reg;
+    uint32_t instruction_word = *next_instr++;
+    (void)instruction_word; /* Stop compiler complaining */
+    reg = (instruction_word >> 8) & 255; \
+    instruction_word = (instruction_word & 0xffff00ff) | (relabel_table[reg] << 8);
+    reg = (instruction_word >> 16) & 255; \
+    instruction_word = (instruction_word & 0xff00ffff) | (relabel_table[reg] << 16);
+    next_instr[-1] = instruction_word;
+    instruction_word = *next_instr++;
+    next_instr[-1] = instruction_word;
+    return next_instr;
+}
+
+static uint32_t *
 relabel_uses_rrok(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
 }
 
 static uint32_t *
+relabel_uses_rrooE(uint32_t *next_instr, unsigned char *relabel_table)
+{
+    int reg;
+    uint32_t instruction_word = *next_instr++;
+    (void)instruction_word; /* Stop compiler complaining */
+    reg = (instruction_word >> 8) & 255; \
+    instruction_word = (instruction_word & 0xffff00ff) | (relabel_table[reg] << 8);
+    reg = (instruction_word >> 16) & 255; \
+    instruction_word = (instruction_word & 0xff00ffff) | (relabel_table[reg] << 16);
+    next_instr[-1] = instruction_word;
+    instruction_word = *next_instr++;
+    next_instr[-1] = instruction_word;
+    return next_instr;
+}
+
+static uint32_t *
+relabel_uses_rroooE(uint32_t *next_instr, unsigned char *relabel_table)
+{
+    int reg;
+    uint32_t instruction_word = *next_instr++;
+    (void)instruction_word; /* Stop compiler complaining */
+    reg = (instruction_word >> 8) & 255; \
+    instruction_word = (instruction_word & 0xffff00ff) | (relabel_table[reg] << 8);
+    reg = (instruction_word >> 16) & 255; \
+    instruction_word = (instruction_word & 0xff00ffff) | (relabel_table[reg] << 16);
+    next_instr[-1] = instruction_word;
+    instruction_word = *next_instr++;
+    next_instr[-1] = instruction_word;
+    return next_instr;
+}
+
+static uint32_t *
 relabel_uses_rrr(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
 }
 
 static uint32_t *
-relabel_uses_rrrE(uint32_t *next_instr, unsigned char *relabel_table)
+relabel_uses_rrrKE(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
-relabel_uses_rrrrE(uint32_t *next_instr, unsigned char *relabel_table)
+relabel_uses_rrrokE(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
     uint32_t instruction_word = *next_instr++;
     instruction_word = (instruction_word & 0x00ffffff) | (relabel_table[reg] << 24);
     next_instr[-1] = instruction_word;
     instruction_word = *next_instr++;
-    reg = instruction_word & 255; \
-    instruction_word = (instruction_word & 0xffffff00) | relabel_table[reg];
-    next_instr[-1] = instruction_word;
-    return next_instr;
-}
-
-static uint32_t *
-relabel_uses_rrrroE(uint32_t *next_instr, unsigned char *relabel_table)
-{
-    int reg;
-    uint32_t instruction_word = *next_instr++;
-    (void)instruction_word; /* Stop compiler complaining */
-    reg = (instruction_word >> 8) & 255; \
-    instruction_word = (instruction_word & 0xffff00ff) | (relabel_table[reg] << 8);
-    reg = (instruction_word >> 16) & 255; \
-    instruction_word = (instruction_word & 0xff00ffff) | (relabel_table[reg] << 16);
-    reg = (instruction_word >> 24); \
-    instruction_word = (instruction_word & 0x00ffffff) | (relabel_table[reg] << 24);
-    next_instr[-1] = instruction_word;
-    instruction_word = *next_instr++;
-    reg = instruction_word & 255; \
-    instruction_word = (instruction_word & 0xffffff00) | relabel_table[reg];
     next_instr[-1] = instruction_word;
     return next_instr;
 }
 }
 
 static uint32_t *
+relabel_defs_oKE(uint32_t *next_instr, unsigned char *relabel_table)
+{
+    int reg;
+    uint32_t instruction_word = *next_instr++;
+    (void)instruction_word; /* Stop compiler complaining */
+    reg = (instruction_word >> 8) & 255; \
+    instruction_word = (instruction_word & 0xffff00ff) | (relabel_table[reg] << 8);
+    next_instr[-1] = instruction_word;
+    instruction_word = *next_instr++;
+    next_instr[-1] = instruction_word;
+    return next_instr;
+}
+
+static uint32_t *
 relabel_defs_oKKK(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
 }
 
 static uint32_t *
-relabel_defs_roE(uint32_t *next_instr, unsigned char *relabel_table)
+relabel_defs_roK(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
-relabel_defs_roK(uint32_t *next_instr, unsigned char *relabel_table)
+relabel_defs_roKE(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
-relabel_defs_rpE(uint32_t *next_instr, unsigned char *relabel_table)
-{
-    uint32_t instruction_word = *next_instr++;
-    (void)instruction_word; /* Stop compiler complaining */
-    next_instr[-1] = instruction_word;
-    instruction_word = *next_instr++;
-    next_instr[-1] = instruction_word;
-    return next_instr;
-}
-
-static uint32_t *
-relabel_defs_rpoE(uint32_t *next_instr, unsigned char *relabel_table)
-{
-    int reg;
-    uint32_t instruction_word = *next_instr++;
-    (void)instruction_word; /* Stop compiler complaining */
-    reg = (instruction_word >> 24); \
-    instruction_word = (instruction_word & 0x00ffffff) | (relabel_table[reg] << 24);
-    next_instr[-1] = instruction_word;
-    instruction_word = *next_instr++;
-    next_instr[-1] = instruction_word;
-    return next_instr;
-}
-
-static uint32_t *
-relabel_defs_rpooE(uint32_t *next_instr, unsigned char *relabel_table)
-{
-    int reg;
-    uint32_t instruction_word = *next_instr++;
-    (void)instruction_word; /* Stop compiler complaining */
-    reg = (instruction_word >> 24); \
-    instruction_word = (instruction_word & 0x00ffffff) | (relabel_table[reg] << 24);
-    next_instr[-1] = instruction_word;
-    instruction_word = *next_instr++;
-    reg = instruction_word & 255; \
-    instruction_word = (instruction_word & 0xffffff00) | relabel_table[reg];
-    next_instr[-1] = instruction_word;
-    return next_instr;
-}
-
-static uint32_t *
-relabel_defs_rpoooE(uint32_t *next_instr, unsigned char *relabel_table)
-{
-    int reg;
-    uint32_t instruction_word = *next_instr++;
-    (void)instruction_word; /* Stop compiler complaining */
-    reg = (instruction_word >> 24); \
-    instruction_word = (instruction_word & 0x00ffffff) | (relabel_table[reg] << 24);
-    next_instr[-1] = instruction_word;
-    instruction_word = *next_instr++;
-    reg = instruction_word & 255; \
-    instruction_word = (instruction_word & 0xffffff00) | relabel_table[reg];
-    reg = (instruction_word >> 8) & 255; \
-    instruction_word = (instruction_word & 0xffff00ff) | (relabel_table[reg] << 8);
-    next_instr[-1] = instruction_word;
-    return next_instr;
-}
-
-static uint32_t *
 relabel_defs_rr(uint32_t *next_instr, unsigned char *relabel_table)
 {
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
+relabel_defs_rrKE(uint32_t *next_instr, unsigned char *relabel_table)
+{
+    uint32_t instruction_word = *next_instr++;
+    (void)instruction_word; /* Stop compiler complaining */
+    next_instr[-1] = instruction_word;
+    instruction_word = *next_instr++;
+    next_instr[-1] = instruction_word;
+    return next_instr;
+}
+
+static uint32_t *
 relabel_defs_rrk(uint32_t *next_instr, unsigned char *relabel_table)
 {
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
+relabel_defs_rroKE(uint32_t *next_instr, unsigned char *relabel_table)
+{
+    int reg;
+    uint32_t instruction_word = *next_instr++;
+    (void)instruction_word; /* Stop compiler complaining */
+    reg = (instruction_word >> 24); \
+    instruction_word = (instruction_word & 0x00ffffff) | (relabel_table[reg] << 24);
+    next_instr[-1] = instruction_word;
+    instruction_word = *next_instr++;
+    next_instr[-1] = instruction_word;
+    return next_instr;
+}
+
+static uint32_t *
 relabel_defs_rrok(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
 }
 
 static uint32_t *
+relabel_defs_rrooE(uint32_t *next_instr, unsigned char *relabel_table)
+{
+    int reg;
+    uint32_t instruction_word = *next_instr++;
+    (void)instruction_word; /* Stop compiler complaining */
+    reg = (instruction_word >> 24); \
+    instruction_word = (instruction_word & 0x00ffffff) | (relabel_table[reg] << 24);
+    next_instr[-1] = instruction_word;
+    instruction_word = *next_instr++;
+    reg = instruction_word & 255; \
+    instruction_word = (instruction_word & 0xffffff00) | relabel_table[reg];
+    next_instr[-1] = instruction_word;
+    return next_instr;
+}
+
+static uint32_t *
+relabel_defs_rroooE(uint32_t *next_instr, unsigned char *relabel_table)
+{
+    int reg;
+    uint32_t instruction_word = *next_instr++;
+    (void)instruction_word; /* Stop compiler complaining */
+    reg = (instruction_word >> 24); \
+    instruction_word = (instruction_word & 0x00ffffff) | (relabel_table[reg] << 24);
+    next_instr[-1] = instruction_word;
+    instruction_word = *next_instr++;
+    reg = instruction_word & 255; \
+    instruction_word = (instruction_word & 0xffffff00) | relabel_table[reg];
+    reg = (instruction_word >> 8) & 255; \
+    instruction_word = (instruction_word & 0xffff00ff) | (relabel_table[reg] << 8);
+    next_instr[-1] = instruction_word;
+    return next_instr;
+}
+
+static uint32_t *
 relabel_defs_rrr(uint32_t *next_instr, unsigned char *relabel_table)
 {
     uint32_t instruction_word = *next_instr++;
 }
 
 static uint32_t *
-relabel_defs_rrrE(uint32_t *next_instr, unsigned char *relabel_table)
+relabel_defs_rrrKE(uint32_t *next_instr, unsigned char *relabel_table)
 {
     uint32_t instruction_word = *next_instr++;
     (void)instruction_word; /* Stop compiler complaining */
 }
 
 static uint32_t *
-relabel_defs_rrrrE(uint32_t *next_instr, unsigned char *relabel_table)
-{
-    uint32_t instruction_word = *next_instr++;
-    (void)instruction_word; /* Stop compiler complaining */
-    next_instr[-1] = instruction_word;
-    instruction_word = *next_instr++;
-    next_instr[-1] = instruction_word;
-    return next_instr;
-}
-
-static uint32_t *
-relabel_defs_rrrroE(uint32_t *next_instr, unsigned char *relabel_table)
+relabel_defs_rrrokE(uint32_t *next_instr, unsigned char *relabel_table)
 {
     int reg;
     uint32_t instruction_word = *next_instr++;
     (void)instruction_word; /* Stop compiler complaining */
     next_instr[-1] = instruction_word;
     instruction_word = *next_instr++;
-    reg = (instruction_word >> 8) & 255; \
-    instruction_word = (instruction_word & 0xffff00ff) | (relabel_table[reg] << 8);
+    reg = instruction_word & 255; \
+    instruction_word = (instruction_word & 0xffffff00) | relabel_table[reg];
     next_instr[-1] = instruction_word;
     return next_instr;
 }
 }
 
 static HotPyContext *
+get_exit_context_oKE(uint32_t *instr, PyObject *exits)
+{
+    uint32_t instruction_word = *instr++;
+    int e0;
+    PyObject *exit;
+    instruction_word = *instr++;
+    e0 = instruction_word & ((1 << 16)-1); \
+    exit = PyTuple_GetItem(exits, e0);
+    return ((HotPyExitObject *)exit)->exit_context;
+}
+
+static HotPyContext *
 get_exit_context_oKKK(uint32_t *instr, PyObject *exits)
 {
    return NULL;
 }
 
 static HotPyContext *
-get_exit_context_roE(uint32_t *instr, PyObject *exits)
+get_exit_context_roK(uint32_t *instr, PyObject *exits)
+{
+   return NULL;
+}
+
+static HotPyContext *
+get_exit_context_roKE(uint32_t *instr, PyObject *exits)
 {
     uint32_t instruction_word = *instr++;
     int e0;
     PyObject *exit;
     instruction_word = *instr++;
-    e0 = instruction_word & ((1 << 16)-1); \
+    e0 = instruction_word >> 16; \
     exit = PyTuple_GetItem(exits, e0);
     return ((HotPyExitObject *)exit)->exit_context;
 }
 
 static HotPyContext *
-get_exit_context_roK(uint32_t *instr, PyObject *exits)
-{
-   return NULL;
-}
-
-static HotPyContext *
 get_exit_context_rok(uint32_t *instr, PyObject *exits)
 {
    return NULL;
 }
 
 static HotPyContext *
-get_exit_context_rpE(uint32_t *instr, PyObject *exits)
-{
-    uint32_t instruction_word = *instr++;
-    int e0;
-    PyObject *exit;
-    instruction_word = *instr++;
-    e0 = instruction_word & ((1 << 16)-1); \
-    exit = PyTuple_GetItem(exits, e0);
-    return ((HotPyExitObject *)exit)->exit_context;
-}
-
-static HotPyContext *
-get_exit_context_rpoE(uint32_t *instr, PyObject *exits)
-{
-    uint32_t instruction_word = *instr++;
-    int e0;
-    PyObject *exit;
-    instruction_word = *instr++;
-    e0 = instruction_word & ((1 << 16)-1); \
-    exit = PyTuple_GetItem(exits, e0);
-    return ((HotPyExitObject *)exit)->exit_context;
-}
-
-static HotPyContext *
-get_exit_context_rpooE(uint32_t *instr, PyObject *exits)
-{
-    uint32_t instruction_word = *instr++;
-    int e0;
-    PyObject *exit;
-    instruction_word = *instr++;
-    e0 = instruction_word >> 16; \
-    exit = PyTuple_GetItem(exits, e0);
-    return ((HotPyExitObject *)exit)->exit_context;
-}
-
-static HotPyContext *
-get_exit_context_rpoooE(uint32_t *instr, PyObject *exits)
-{
-    uint32_t instruction_word = *instr++;
-    int e0;
-    PyObject *exit;
-    instruction_word = *instr++;
-    e0 = instruction_word >> 16; \
-    exit = PyTuple_GetItem(exits, e0);
-    return ((HotPyExitObject *)exit)->exit_context;
-}
-
-static HotPyContext *
 get_exit_context_rr(uint32_t *instr, PyObject *exits)
 {
    return NULL;
 }
 
 static HotPyContext *
+get_exit_context_rrKE(uint32_t *instr, PyObject *exits)
+{
+    uint32_t instruction_word = *instr++;
+    int e0;
+    PyObject *exit;
+    instruction_word = *instr++;
+    e0 = instruction_word >> 16; \
+    exit = PyTuple_GetItem(exits, e0);
+    return ((HotPyExitObject *)exit)->exit_context;
+}
+
+static HotPyContext *
 get_exit_context_rrk(uint32_t *instr, PyObject *exits)
 {
    return NULL;
 }
 
 static HotPyContext *
+get_exit_context_rroKE(uint32_t *instr, PyObject *exits)
+{
+    uint32_t instruction_word = *instr++;
+    int e0;
+    PyObject *exit;
+    instruction_word = *instr++;
+    e0 = instruction_word >> 16; \
+    exit = PyTuple_GetItem(exits, e0);
+    return ((HotPyExitObject *)exit)->exit_context;
+}
+
+static HotPyContext *
 get_exit_context_rrok(uint32_t *instr, PyObject *exits)
 {
    return NULL;
 }
 
 static HotPyContext *
+get_exit_context_rrooE(uint32_t *instr, PyObject *exits)
+{
+    uint32_t instruction_word = *instr++;
+    int e0;
+    PyObject *exit;
+    instruction_word = *instr++;
+    e0 = instruction_word >> 16; \
+    exit = PyTuple_GetItem(exits, e0);
+    return ((HotPyExitObject *)exit)->exit_context;
+}
+
+static HotPyContext *
+get_exit_context_rroooE(uint32_t *instr, PyObject *exits)
+{
+    uint32_t instruction_word = *instr++;
+    int e0;
+    PyObject *exit;
+    instruction_word = *instr++;
+    e0 = instruction_word >> 16; \
+    exit = PyTuple_GetItem(exits, e0);
+    return ((HotPyExitObject *)exit)->exit_context;
+}
+
+static HotPyContext *
 get_exit_context_rrr(uint32_t *instr, PyObject *exits)
 {
    return NULL;
 }
 
 static HotPyContext *
-get_exit_context_rrrE(uint32_t *instr, PyObject *exits)
+get_exit_context_rrrKE(uint32_t *instr, PyObject *exits)
 {
     uint32_t instruction_word = *instr++;
     int e0;
     PyObject *exit;
     instruction_word = *instr++;
-    e0 = instruction_word & ((1 << 16)-1); \
+    e0 = instruction_word >> 16; \
     exit = PyTuple_GetItem(exits, e0);
     return ((HotPyExitObject *)exit)->exit_context;
 }
 }
 
 static HotPyContext *
-get_exit_context_rrrrE(uint32_t *instr, PyObject *exits)
+get_exit_context_rrrokE(uint32_t *instr, PyObject *exits)
 {
     uint32_t instruction_word = *instr++;
     int e0;
     return ((HotPyExitObject *)exit)->exit_context;
 }
 
-static HotPyContext *
-get_exit_context_rrrroE(uint32_t *instr, PyObject *exits)
-{
-    uint32_t instruction_word = *instr++;
-    int e0;
-    PyObject *exit;
-    instruction_word = *instr++;
-    e0 = instruction_word >> 16; \
-    exit = PyTuple_GetItem(exits, e0);
-    return ((HotPyExitObject *)exit)->exit_context;
-}
-

Python/register_interpreter.c

             FAST_DISPATCH();
 
         TARGET(CALL_WRAPPER_NEXT)
-            FORMAT_rroE;
-            PyObject *arg = registers[r1];
-            PyObject *wrapper = registers[r0];
+            FORMAT_roKE;
+            PyObject *arg = registers[r0];
+            PyObject *wrapper = CONSTANT(k0);
             PyObject *x;
             void *wrapped = ((PyWrapperDescrObject *)wrapper)->d_wrapped;
             assert(Py_TYPE(arg)->tp_iternext == (iternextfunc)wrapped);
                 PUSH(x);
                 goto materialised;
             }
-            SET_REGISTER(r2, x);
+            SET_REGISTER(r1, x);
             tstate->execution_context = NULL;
             DISPATCH();
 
         TARGET(CALL_WRAPPER_UNARY)
-            FORMAT_rroE;
-            PyObject *arg = registers[r1];
-            PyObject *wrapper = registers[r0];
+            FORMAT_roKE;
+            PyObject *arg = registers[r0];
+            PyObject *wrapper = CONSTANT(k0);
             void *wrapped = ((PyWrapperDescrObject *)wrapper)->d_wrapped;
             PyObject *x;
             exit = GETEXIT(e0);
                 assert(PyErr_Occurred());
                 goto error_with_exit;
             }
-            SET_REGISTER(r2, x);
+            SET_REGISTER(r1, x);
             tstate->execution_context = NULL;
             DISPATCH();
 
         TARGET(CALL_WRAPPER_BINARY)
-            FORMAT_rrroE;
-            PyObject *wrapper = registers[r0];
-            PyObject *arg0 = registers[r1];
-            PyObject *arg1 = registers[r2];
+            FORMAT_rroKE;
+            PyObject *wrapper = CONSTANT(k0);
+            PyObject *arg0 = registers[r0];
+            PyObject *arg1 = registers[r1];
             void *wrapped = ((PyWrapperDescrObject *)wrapper)->d_wrapped;
             PyObject *x;
             exit = GETEXIT(e0);
                 assert(PyErr_Occurred());
                 goto error_with_exit;
             }
-            SET_REGISTER(r3, x);
+            SET_REGISTER(r2, x);
             tstate->execution_context = NULL;
             DISPATCH();
 
         TARGET(CALL_WRAPPER_TRINARY_PROC)
-            FORMAT_rrrrE;
-            PyObject *wrapper = registers[r0];
-            PyObject *arg0 = registers[r1];
-            PyObject *arg1 = registers[r2];
-            PyObject *arg2 = registers[r3];
+            FORMAT_rrrKE;
+            PyObject *wrapper = CONSTANT(k0);
+            PyObject *arg0 = registers[r0];
+            PyObject *arg1 = registers[r1];
+            PyObject *arg2 = registers[r2];
             void *wrapped = ((PyWrapperDescrObject *)wrapper)->d_wrapped;
             int err;
             exit = GETEXIT(e0);
             DISPATCH();
 
         TARGET(CALL_WRAPPER_BINARY_NULL_PROC)
-            FORMAT_rrrE;
-            PyObject *wrapper = registers[r0];
-            PyObject *arg0 = registers[r1];
-            PyObject *arg1 = registers[r2];
+            FORMAT_rrKE;
+            PyObject *wrapper = CONSTANT(k0);
+            PyObject *arg0 = registers[r0];
+            PyObject *arg1 = registers[r1];
             void *wrapped = ((PyWrapperDescrObject *)wrapper)->d_wrapped;
             int err;
             exit = GETEXIT(e0);
             DISPATCH();
 
         TARGET(CALL_CFUNC_0)
-            FORMAT_roE;
-            PyObject *func = registers[r0];
+            FORMAT_oKE;
+            PyObject *func = CONSTANT(k0);
             PyObject *self = PyCFunction_GET_SELF(func);
             PyCFunction meth = PyCFunction_GET_FUNCTION(func);
             PyObject *x;
                 assert(PyErr_Occurred());
                 goto error_with_exit;
             }
+            SET_REGISTER(r0, x);
+            tstate->execution_context = NULL;
+            DISPATCH();
+
+        TARGET(CALL_CFUNC_1)
+            FORMAT_roKE;
+            PyObject *func = CONSTANT(k0);
+            PyObject *args = registers[r0];
+            PyObject *self = PyCFunction_GET_SELF(func);
+            PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+            PyObject *x;
+            exit = GETEXIT(e0);
+            tstate->execution_context = exit->exit_context;
+            x = (*meth)(self, args);
+            if (tstate->execution_context == NULL) {
+                if (x)
+                    PUSH(x);
+                goto materialised;
+            }
+            if (x == NULL) {
+                assert(PyErr_Occurred());
+                goto error_with_exit;
+            }
+            SET_REGISTER(r1, x);
+            tstate->execution_context = NULL;
+            DISPATCH();
+
+        TARGET(CALL_CFUNC_2)
+            FORMAT_rroKE;
+            PyObject *func = CONSTANT(k0);
+            PyObject *args = registers[r0];
+            PyObject *kws = registers[r1];
+            PyObject *self = PyCFunction_GET_SELF(func);
+            PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+            PyObject *x;
+            exit = GETEXIT(e0);
+            tstate->execution_context = exit->exit_context;
+            x = (*(PyCFunctionWithKeywords)meth)(self, args, kws);
+            if (tstate->execution_context == NULL) {
+                if (x)
+                    PUSH(x);
+                goto materialised;
+            }
+            if (x == NULL) {
+                goto error_with_exit;
+            }
+            SET_REGISTER(r2, x);
+            tstate->execution_context = NULL;
+            DISPATCH();
+
+        TARGET(CALL_CMETH_0)
+            FORMAT_roKE;
+            PyObject *desc = CONSTANT(k0);
+            PyObject *self = registers[r0];
+            PyCFunction meth;
+            PyObject *x;
+            assert(Py_TYPE(desc) == &PyMethodDescr_Type);
+            meth = ((PyMethodDescrObject *)desc)->d_method->ml_meth;
+            exit = GETEXIT(e0);
+            tstate->execution_context = exit->exit_context;
+            x = (*meth)(self, NULL);
+            if (tstate->execution_context == NULL) {
+                if (x)
+                    PUSH(x);
+                goto materialised;
+            }
+            if (x == NULL) {
+                assert(PyErr_Occurred());
+                goto error_with_exit;
+            }
             SET_REGISTER(r1, x);
             tstate->execution_context = NULL;
             DISPATCH();
 
-        TARGET(CALL_CFUNC_1)
-            FORMAT_rroE;
-            PyObject *func = registers[r0];
+        TARGET(CALL_CMETH_1)
+            FORMAT_rroKE;
+            PyObject *desc = CONSTANT(k0);
+            PyObject *self = registers[r0];
             PyObject *args = registers[r1];
-            PyObject *self = PyCFunction_GET_SELF(func);
-            PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+            PyCFunction meth;
             PyObject *x;
+            assert(Py_TYPE(desc) == &PyMethodDescr_Type);
+            meth = ((PyMethodDescrObject *)desc)->d_method->ml_meth;
             exit = GETEXIT(e0);
             tstate->execution_context = exit->exit_context;
             x = (*meth)(self, args);
             tstate->execution_context = NULL;
             DISPATCH();
 
-        TARGET(CALL_CFUNC_2)
-            FORMAT_rrroE;
-            PyObject *func = registers[r0];
+        TARGET(CALL_CMETH_2)
+            FORMAT_rrrokE;
+            PyObject *desc = CONSTANT(k0);
+            PyObject *self = registers[r0];
             PyObject *args = registers[r1];
             PyObject *kws = registers[r2];
-            PyObject *self = PyCFunction_GET_SELF(func);
-            PyCFunction meth = PyCFunction_GET_FUNCTION(func);
-            PyObject *x;
-            exit = GETEXIT(e0);
-            tstate->execution_context = exit->exit_context;
-            x = (*(PyCFunctionWithKeywords)meth)(self, args, kws);
-            if (tstate->execution_context == NULL) {
-                if (x)
-                    PUSH(x);
-                goto materialised;
-            }
-            if (x == NULL) {
-                goto error_with_exit;
-            }
-            SET_REGISTER(r3, x);
-            tstate->execution_context = NULL;
-            DISPATCH();
-
-        TARGET(CALL_CMETH_0)
-            FORMAT_rroE;
-            PyObject *desc = registers[r0];
-            PyObject *self = registers[r1];
-            PyCFunction meth;
-            PyObject *x;
-            assert(Py_TYPE(desc) == &PyMethodDescr_Type);
-            meth = ((PyMethodDescrObject *)desc)->d_method->ml_meth;
-            exit = GETEXIT(e0);
-            tstate->execution_context = exit->exit_context;
-            x = (*meth)(self, NULL);
-            if (tstate->execution_context == NULL) {
-                if (x)
-                    PUSH(x);
-                goto materialised;
-            }
-            if (x == NULL) {
-                assert(PyErr_Occurred());
-                goto error_with_exit;
-            }
-            SET_REGISTER(r2, x);
-            tstate->execution_context = NULL;
-            DISPATCH();
-
-        TARGET(CALL_CMETH_1)
-            FORMAT_rrroE;
-            PyObject *desc = registers[r0];
-            PyObject *self = registers[r1];
-            PyObject *args = registers[r2];
-            PyCFunction meth;
-            PyObject *x;
-            assert(Py_TYPE(desc) == &PyMethodDescr_Type);
-            meth = ((PyMethodDescrObject *)desc)->d_method->ml_meth;
-            exit = GETEXIT(e0);
-            tstate->execution_context = exit->exit_context;
-            x = (*meth)(self, args);
-            if (tstate->execution_context == NULL) {
-                if (x)
-                    PUSH(x);
-                goto materialised;
-            }
-            if (x == NULL) {
-                assert(PyErr_Occurred());
-                goto error_with_exit;
-            }
-            SET_REGISTER(r3, x);
-            tstate->execution_context = NULL;
-            DISPATCH();
-
-        TARGET(CALL_CMETH_2)
-            FORMAT_rrrroE;
-            PyObject *desc = registers[r0];
-            PyObject *self = registers[r1];
-            PyObject *args = registers[r2];
-            PyObject *kws = registers[r3];
             PyCFunction meth;
             PyObject *x;
             assert(Py_TYPE(desc) == &PyMethodDescr_Type);
             if (x == NULL) {
                 goto error_with_exit;
             }
-            SET_REGISTER(r4, x);
+            SET_REGISTER(r3, x);
             tstate->execution_context = NULL;
             DISPATCH();
 
             DISPATCH();
 
         TARGET(ONE_ARG)
-            FORMAT_rpoE;
+            FORMAT_rroE;
             PyObject *args = registers[r1];
             Py_ssize_t size = PyTuple_Size(args);
             if (size != 1) {
             DISPATCH();
 
         TARGET(ONE_PLUS_ARGS)
-            FORMAT_rpooE;
+            FORMAT_rrooE;
             PyObject *args = registers[r1];
             Py_ssize_t size = PyTuple_Size(args);
             if (size < 1) {
             DISPATCH();
 
         TARGET(TWO_ARGS)
-            FORMAT_rpooE;
+            FORMAT_rrooE;
             PyObject *args = registers[r1];
             Py_ssize_t size = PyTuple_Size(args);
             if (size != 2) {
             DISPATCH();
 
         TARGET(THREE_ARGS)
-            FORMAT_rpoooE;
+            FORMAT_rroooE;
             PyObject *args = registers[r1];
             Py_ssize_t size = PyTuple_Size(args);
             if (size != 3) {
             DISPATCH();
 
         TARGET(NO_ARGS)
-            FORMAT_rpE;
+            FORMAT_rrE;
             PyObject *args = registers[r1];
             Py_ssize_t size = PyTuple_Size(args);
             if (size) {

Python/trace_D_O_C.c

 }
 
 static HotPyContext *
+call_cfunction(HotPyOptimiser *x, PyObject *f, int args)
+{
+    HotPy_DOC *opt = (HotPy_DOC *)x;
+    HotPyContext *context;
+    defer_stack_below(x, args);
+    materialise_stack_top(x, args);
+    context = x->next->call_cfunction(x->next, f, args);
+    if (context)
+        save_state_to_context(x, context);
+    PUSH(real_value());
+    return context;
+}
+
+static HotPyContext *
+call_cmethod(HotPyOptimiser *x, PyObject *f, int args)
+{
+    HotPy_DOC *opt = (HotPy_DOC *)x;
+    HotPyContext *context;
+    defer_stack_below(x, args+1);
+    materialise_stack_top(x, args+1);
+    context = x->next->call_cmethod(x->next, f, args);
+    if (context)
+        save_state_to_context(x, context);
+    PUSH(real_value());
+    return context;
+}
+
+static HotPyContext *
+call_wrapper(HotPyOptimiser *x, int opcode, PyObject *w)
+{
+    HotPy_DOC *opt = (HotPy_DOC *)x;
+    HotPyContext *context;
+    int args;
+    int proc = 0;
+    switch (opcode) {
+    case CALL_WRAPPER_TRINARY_PROC:
+        args = 3;
+        proc = 1;
+        break;
+    case CALL_WRAPPER_BINARY_NULL_PROC:
+        proc = 1;
+        args = 2;
+        break;
+    case CALL_WRAPPER_BINARY:
+        args = 2;
+        break;
+    case CALL_WRAPPER_NEXT: case CALL_WRAPPER_UNARY:
+        args = 1;
+        break;
+    default:
+        assert("Unknown opcode" && 0);
+        abort();
+    }
+    defer_stack_below(x, args);
+    materialise_stack_top(x, args);
+    context = x->next->call_wrapper(x->next, opcode, w);
+    if (context)
+        save_state_to_context(x, context);
+    if (!proc)
+        PUSH(real_value());
+    return context;
+}
+
+static HotPyContext *
 opcode_with_exit(HotPyOptimiser *x, int op)
 {
     HotPy_DOC *opt = (HotPy_DOC *)x;
             Py_DECREF(u);
         }
         break;
-    case CALL_CFUNC_0:
-        defer_stack_below(x, 1);
-        materialise_stack_top(x, 1);
-        context = x->next->opcode_with_exit(x->next, op);
-        if (context)
-            save_state_to_context(x, context);
-        PUSH(real_value());
-        break;
-    case CALL_CFUNC_1: case CALL_CMETH_0:
+    case NO_ARGS:
         defer_stack_below(x, 2);
-        materialise_stack_top(x, 2);