1 // $Id: peephole.c,v 1.6 2003/10/13 22:53:04 iain Exp $
2 // Peephole optimiser for git
8 extern void resetPeepholeOptimiser ()
13 #define REPLACE_SINGLE(lastOp,thisOp,newOp) \
14 case label_ ## thisOp: \
15 if (sLastOp == label_ ## lastOp) \
17 op = label_ ## newOp; \
18 goto replaceNoOperands; \
22 #define CASE_NO_OPERANDS(lastOp,newOp) \
23 case label_ ## lastOp: op = label_ ## newOp; goto replaceNoOperands
25 #define CASE_ONE_OPERAND(lastOp,newOp) \
26 case label_ ## lastOp: op = label_ ## newOp; goto replaceOneOperand
28 #define REPLACE_STORE(storeOp) \
29 case label_ ## storeOp: \
32 CASE_NO_OPERANDS (add_discard, add_ ## storeOp); \
33 CASE_NO_OPERANDS (sub_discard, sub_ ## storeOp); \
34 CASE_NO_OPERANDS (mul_discard, mul_ ## storeOp); \
35 CASE_NO_OPERANDS (div_discard, div_ ## storeOp); \
36 CASE_NO_OPERANDS (mod_discard, mod_ ## storeOp); \
37 CASE_NO_OPERANDS (neg_discard, neg_ ## storeOp); \
38 CASE_NO_OPERANDS (bitand_discard, bitand_ ## storeOp); \
39 CASE_NO_OPERANDS (bitor_discard, bitor_ ## storeOp); \
40 CASE_NO_OPERANDS (bitxor_discard, bitxor_ ## storeOp); \
41 CASE_NO_OPERANDS (bitnot_discard, bitnot_ ## storeOp); \
42 CASE_NO_OPERANDS (shiftl_discard, shiftl_ ## storeOp); \
43 CASE_NO_OPERANDS (sshiftr_discard, sshiftr_ ## storeOp); \
44 CASE_NO_OPERANDS (ushiftr_discard, ushiftr_ ## storeOp); \
45 CASE_NO_OPERANDS (copys_discard, copys_ ## storeOp); \
46 CASE_NO_OPERANDS (copyb_discard, copyb_ ## storeOp); \
47 CASE_NO_OPERANDS (sexs_discard, sexs_ ## storeOp); \
48 CASE_NO_OPERANDS (sexb_discard, sexb_ ## storeOp); \
49 CASE_NO_OPERANDS (aload_discard, aload_ ## storeOp); \
50 CASE_NO_OPERANDS (aloads_discard, aloads_ ## storeOp); \
51 CASE_NO_OPERANDS (aloadb_discard, aloadb_ ## storeOp); \
52 CASE_NO_OPERANDS (aloadbit_discard, aloadbit_ ## storeOp); \
57 #define REPLACE_L1_L2(mode2) \
58 case label_L2_ ## mode2: \
61 CASE_ONE_OPERAND (L1_const, L1_const_L2_ ## mode2); \
62 CASE_NO_OPERANDS (L1_stack, L1_stack_L2_ ## mode2); \
63 CASE_ONE_OPERAND (L1_local, L1_local_L2_ ## mode2); \
64 CASE_ONE_OPERAND (L1_addr, L1_addr_L2_ ## mode2); \
69 #define REPLACE_LOAD_OP(loadOp,reg) \
70 case label_ ## loadOp: \
73 CASE_ONE_OPERAND (reg ## _const, loadOp ## _ ## reg ## _const); \
74 CASE_NO_OPERANDS (reg ## _stack, loadOp ## _ ## reg ## _stack); \
75 CASE_ONE_OPERAND (reg ## _local, loadOp ## _ ## reg ## _local); \
76 CASE_ONE_OPERAND (reg ## _addr, loadOp ## _ ## reg ## _addr); \
81 extern void emitCode (Label op)
89 REPLACE_SINGLE (args_stack, call_stub_discard, args_stack_call_stub_discard);
90 REPLACE_SINGLE (args_stack, call_stub_addr, args_stack_call_stub_addr);
91 REPLACE_SINGLE (args_stack, call_stub_local, args_stack_call_stub_local);
92 REPLACE_SINGLE (args_stack, call_stub_stack, args_stack_call_stub_stack);
94 REPLACE_STORE (S1_stack);
95 REPLACE_STORE (S1_local);
96 REPLACE_STORE (S1_addr);
98 REPLACE_L1_L2 (const);
99 REPLACE_L1_L2 (stack);
100 REPLACE_L1_L2 (local);
101 REPLACE_L1_L2 (addr);
103 REPLACE_LOAD_OP (return, L1);
104 REPLACE_LOAD_OP (astore, L3);
105 REPLACE_LOAD_OP (astores, L3);
106 REPLACE_LOAD_OP (astoreb, L3);
107 REPLACE_LOAD_OP (astorebit, L3);
115 // The previous opcode has one operand, so
116 // we have to go back two steps to update it.
117 temp = undoEmit(); // Save the operand.
118 undoEmit(); // Remove the old opcode.
119 emitFinalCode (op); // Emit the new opcode.
120 emitData (temp); // Emit the operand again.