From 1d9dec227ae44f53f0697474bc66204248d2aca7 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Sat, 18 Jan 2025 15:08:11 -0500 Subject: [PATCH 1/4] Fix HuCC's rescheduler to preserve the primary-register when using array indices that are local stack variables. Stop spamming the entire list of HuCC macros to the listing file, it's too long! Clean up the stack modification macros a bit, and don't output any code when the stack delta is zero when balancing the stack before a "goto". --- include/hucc/hucc-codegen.asm | 223 ++++++++++++++++++---------------- src/hucc/code.c | 49 +++++--- src/hucc/defs.h | 20 +-- src/hucc/optimize.c | 52 +++++--- 4 files changed, 202 insertions(+), 142 deletions(-) diff --git a/include/hucc/hucc-codegen.asm b/include/hucc/hucc-codegen.asm index 4a0168ec..4043ca67 100644 --- a/include/hucc/hucc-codegen.asm +++ b/include/hucc/hucc-codegen.asm @@ -57,6 +57,8 @@ + .nolist + ; *************************************************************************** ; *************************************************************************** ; i-code that retires the primary register contents @@ -291,25 +293,6 @@ __fgetub .macro ; *************************************************************************** ; *************************************************************************** -; ************** -; the compiler can generate this to aid debugging C data-stack -; balance problems before/after a function call - -__calling .macro - ldx <__sp - phx - .endm - -; ************** -; the compiler can generate this to aid debugging C data-stack -; balance problems before/after a function call - -__called .macro - plx - cpx <__sp -!hang: bne !hang- - .endm - ; ************** __call .macro @@ -360,31 +343,31 @@ __return .macro ; main C stack for local variables and arguments __modsp .macro ; __STACK - .if (\1 < 0) - .if (\1 == -2) + .if ((\1 >= 0) && (\1 < 65536)) + .if (\1 == 2) + inc <__sp + inc <__sp + .else + tax + lda <__sp + clc + adc #\1 + sta <__sp + txa + .endif + .else + .if (\1 == -2) dec <__sp dec <__sp .else - lda.l <__sp + lda <__sp clc - adc.l #\1 - sta.l <__sp + adc #\1 + sta <__sp .endif .if HUCC_DEBUG_SP !overflow: bmi !overflow- .endif - .else - .if (\1 == 2) - inc <__sp - inc <__sp - .else - tax - lda.l <__sp - clc - adc.l #\1 - sta.l <__sp - txa - .endif .endif .endm @@ -392,11 +375,13 @@ __modsp .macro ; __STACK ; main C stack for local variables and arguments ; this is used to adjust the stack in a C "goto" -__modsp_sym .macro ; __STACK +__modsp_goto .macro ; __STACK + .if (\1 != 0) lda.l <__sp clc - adc.l #\1 + adc #\1 sta.l <__sp + .endif .endm ; ************** @@ -1387,7 +1372,7 @@ __uge_b.umq .macro ; C is true (1) if Y:A == memory-value, else false (0) ; this MUST set the C flag for the subsequent branches! -__equ_w.ws .macro +__equ_w.ws .macro ; __STACK ldx <__sp cmp.l <__stack + \1, x bne !false+ @@ -1403,7 +1388,7 @@ __equ_w.ws .macro ; C is true (1) if Y:A != memory-value, else false (0) ; this MUST set the C flag for the subsequent branches! -__neq_w.ws .macro +__neq_w.ws .macro ; __STACK ldx <__sp sec eor.l <__stack + \1, x @@ -1420,7 +1405,7 @@ __neq_w.ws .macro ; C is true (1) if Y:A < memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__slt_w.ws .macro +__slt_w.ws .macro ; __STACK ldx <__sp cmp.l <__stack + \1, x; Subtract memory from Y:A. tya @@ -1435,7 +1420,7 @@ __slt_w.ws .macro ; C is true (1) if Y:A <= memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__sle_w.ws .macro +__sle_w.ws .macro ; __STACK ldx <__sp clc ; Subtract memory+1 from Y:A. sbc.l <__stack + \1, x @@ -1451,7 +1436,7 @@ __sle_w.ws .macro ; C is true (1) if Y:A > memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__sgt_w.ws .macro +__sgt_w.ws .macro ; __STACK ldx <__sp clc ; Subtract memory+1 from Y:A. sbc.l <__stack + \1, x @@ -1468,7 +1453,7 @@ __sgt_w.ws .macro ; C is true (1) if Y:A >= memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__sge_w.ws .macro +__sge_w.ws .macro ; __STACK ldx <__sp cmp.l <__stack + \1, x; Subtract memory from Y:A. tya @@ -1484,7 +1469,7 @@ __sge_w.ws .macro ; C is true (1) if Y:A < memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__ult_w.ws .macro +__ult_w.ws .macro ; __STACK ldx <__sp cmp.l <__stack + \1, x; Subtract memory from Y:A. tya @@ -1499,7 +1484,7 @@ __ult_w.ws .macro ; C is true (1) if Y:A <= memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__ule_w.ws .macro +__ule_w.ws .macro ; __STACK ldx <__sp clc ; Subtract memory+1 from Y:A. sbc.l <__stack + \1, x @@ -1515,7 +1500,7 @@ __ule_w.ws .macro ; C is true (1) if Y:A > memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__ugt_w.ws .macro +__ugt_w.ws .macro ; __STACK ldx <__sp clc ; Subtract memory+1 from Y:A. sbc.l <__stack + \1, x @@ -1528,7 +1513,7 @@ __ugt_w.ws .macro ; C is true (1) if Y:A >= memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__uge_w.ws .macro +__uge_w.ws .macro ; __STACK ldx <__sp cmp.l <__stack + \1, x; Subtract memory from Y:A. tya @@ -1540,7 +1525,7 @@ __uge_w.ws .macro ; C is true (1) if Y:A == memory-value, else false (0) ; this MUST set the C flag for the subsequent branches! -__equ_w.us .macro +__equ_w.us .macro ; __STACK ldx <__sp cmp <__stack + \1, x bne !false+ @@ -1555,7 +1540,7 @@ __equ_w.us .macro ; C is true (1) if Y:A != memory-value, else false (0) ; this MUST set the C flag for the subsequent branches! -__neq_w.us .macro +__neq_w.us .macro ; __STACK ldx <__sp sec eor <__stack + \1, x @@ -1571,7 +1556,7 @@ __neq_w.us .macro ; C is true (1) if Y:A < memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__slt_w.us .macro +__slt_w.us .macro ; __STACK ldx <__sp cmp <__stack + \1, x; Subtract memory from Y:A. tya @@ -1586,7 +1571,7 @@ __slt_w.us .macro ; C is true (1) if Y:A <= memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__sle_w.us .macro +__sle_w.us .macro ; __STACK ldx <__sp clc ; Subtract memory+1 from Y:A. sbc <__stack + \1, x @@ -1602,7 +1587,7 @@ __sle_w.us .macro ; C is true (1) if Y:A > memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__sgt_w.us .macro +__sgt_w.us .macro ; __STACK ldx <__sp clc ; Subtract memory+1 from Y:A. sbc <__stack + \1, x @@ -1619,7 +1604,7 @@ __sgt_w.us .macro ; C is true (1) if Y:A >= memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__sge_w.us .macro +__sge_w.us .macro ; __STACK ldx <__sp cmp <__stack + \1, x; Subtract memory from Y:A. tya @@ -1635,7 +1620,7 @@ __sge_w.us .macro ; C is true (1) if Y:A < memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__ult_w.us .macro +__ult_w.us .macro ; __STACK ldx <__sp cmp <__stack + \1, x; Subtract memory from Y:A. tya @@ -1650,7 +1635,7 @@ __ult_w.us .macro ; C is true (1) if Y:A <= memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__ule_w.us .macro +__ule_w.us .macro ; __STACK ldx <__sp clc ; Subtract memory+1 from Y:A. sbc <__stack + \1, x @@ -1666,7 +1651,7 @@ __ule_w.us .macro ; C is true (1) if Y:A > memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__ugt_w.us .macro +__ugt_w.us .macro ; __STACK ldx <__sp clc ; Subtract memory+1 from Y:A. sbc <__stack + \1, x @@ -1679,7 +1664,7 @@ __ugt_w.us .macro ; C is true (1) if Y:A >= memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__uge_w.us .macro +__uge_w.us .macro ; __STACK ldx <__sp cmp <__stack + \1, x; Subtract memory from Y:A. tya @@ -1691,7 +1676,7 @@ __uge_w.us .macro ; C is true (1) if A == memory-value, else false (0) ; this MUST set the C flag for the subsequent branches! -__equ_b.usq .macro +__equ_b.usq .macro ; __STACK ldx <__sp cmp <__stack + \1, x beq !+ @@ -1704,7 +1689,7 @@ __equ_b.usq .macro ; C is true (1) if A != memory-value, else false (0) ; this MUST set the C flag for the subsequent branches! -__neq_b.usq .macro +__neq_b.usq .macro ; __STACK ldx <__sp sec eor <__stack + \1, x @@ -1718,7 +1703,7 @@ __neq_b.usq .macro ; C is true (1) if A < memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__slt_b.bsq .macro +__slt_b.bsq .macro ; __STACK ldx <__sp sec ; Subtract memory from A. sbc <__stack + \1, x @@ -1732,7 +1717,7 @@ __slt_b.bsq .macro ; C is true (1) if A <= memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__sle_b.bsq .macro +__sle_b.bsq .macro ; __STACK ldx <__sp clc ; Subtract memory+1 from A. sbc <__stack + \1, x @@ -1746,7 +1731,7 @@ __sle_b.bsq .macro ; C is true (1) if A > memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__sgt_b.bsq .macro +__sgt_b.bsq .macro ; __STACK ldx <__sp clc ; Subtract memory+1 from A. sbc.l <__stack + \1, x @@ -1761,7 +1746,7 @@ __sgt_b.bsq .macro ; C is true (1) if A >= memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__sge_b.bsq .macro +__sge_b.bsq .macro ; __STACK ldx <__sp sec ; Subtract memory from A. sbc <__stack + \1, x @@ -1776,7 +1761,7 @@ __sge_b.bsq .macro ; C is true (1) if A < memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__ult_b.usq .macro +__ult_b.usq .macro ; __STACK ldx <__sp cmp <__stack + \1, x; Subtract memory from A. ror a ; CC if A < memory. @@ -1789,7 +1774,7 @@ __ult_b.usq .macro ; C is true (1) if A <= memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__ule_b.usq .macro +__ule_b.usq .macro ; __STACK ldx <__sp clc ; Subtract memory+1 from A. sbc <__stack + \1, x @@ -1803,7 +1788,7 @@ __ule_b.usq .macro ; C is true (1) if A > memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__ugt_b.usq .macro +__ugt_b.usq .macro ; __STACK ldx <__sp clc ; Subtract memory+1 from A. sbc <__stack + \1, x; CS if A > memory. @@ -1814,7 +1799,7 @@ __ugt_b.usq .macro ; C is true (1) if A >= memory-value, else false (0) ; this MUST set the C flag for the susequent branches! -__uge_b.usq .macro +__uge_b.usq .macro ; __STACK ldx <__sp cmp <__stack + \1, x; Subtract memory from A. ; CS if A >= memory. @@ -2780,7 +2765,7 @@ __ld.uiq .macro ; ************** __lea.s .macro ; __STACK - lda.l <__sp + lda <__sp clc adc.l #__stack + (\1) ldy.h #__stack @@ -2848,53 +2833,53 @@ __ldx.umq .macro ; ************** -__ld2x.wmq .macro +__ld2x.wm .macro + tax lda.l \1 asl a - tax + sax .endm ; ************** -__ld2x.bmq .macro +__ld2x.bm .macro + tax lda \1 asl a - tax + sax .endm ; ************** -__ld2x.umq .macro +__ld2x.um .macro + tax lda \1 asl a - tax + sax .endm ; ************** -__ld2x.wm .macro - tax +__ld2x.wmq .macro lda.l \1 asl a - sax + tax .endm ; ************** -__ld2x.bm .macro - tax +__ld2x.bmq .macro lda \1 asl a - sax + tax .endm ; ************** -__ld2x.um .macro - tax +__ld2x.umq .macro lda \1 asl a - sax + tax .endm ; ************** @@ -3182,83 +3167,110 @@ __ld.usq .macro ; __STACK ; ************** +__ldx.ws .macro ; __STACK + phy + ldy <__sp + ldx.l <__stack + \1, y + ply + .endm + +; ************** + +__ldx.bs .macro ; __STACK + phy + ldy <__sp + ldx <__stack + \1, y + ply + .endm + +; ************** + +__ldx.us .macro ; __STACK + phy + ldy <__sp + ldx <__stack + \1, y + ply + .endm + +; ************** + __ldx.wsq .macro ; __STACK - ldy.l <__sp + ldy <__sp ldx.l <__stack + \1, y .endm ; ************** __ldx.bsq .macro ; __STACK - ldy.l <__sp + ldy <__sp ldx <__stack + \1, y .endm ; ************** __ldx.usq .macro ; __STACK - ldy.l <__sp + ldy <__sp ldx <__stack + \1, y .endm ; ************** -__ld2x.wsq .macro ; __STACK - ldx.l <__sp +__ld2x.ws .macro ; __STACK + ldx <__sp + pha lda.l <__stack + \1, x asl a tax + pla .endm ; ************** -__ld2x.bsq .macro ; __STACK - ldx.l <__sp +__ld2x.bs .macro ; __STACK + ldx <__sp + pha lda <__stack + \1, x asl a tax + pla .endm ; ************** -__ld2x.usq .macro ; __STACK - ldx.l <__sp +__ld2x.us .macro ; __STACK + ldx <__sp + pha lda <__stack + \1, x asl a tax + pla .endm ; ************** -__ld2x.ws .macro ; __STACK - ldx.l <__sp - pha +__ld2x.wsq .macro ; __STACK + ldx <__sp lda.l <__stack + \1, x asl a tax - pla .endm ; ************** -__ld2x.bs .macro ; __STACK - ldx.l <__sp - pha +__ld2x.bsq .macro ; __STACK + ldx <__sp lda <__stack + \1, x asl a tax - pla .endm ; ************** -__ld2x.us .macro ; __STACK - ldx.l <__sp - pha +__ld2x.usq .macro ; __STACK + ldx <__sp lda <__stack + \1, x asl a tax - pla .endm ; ************** @@ -6175,6 +6187,7 @@ __ldd_s_b .macro ; __STACK .endm + .list ; *************************************************************************** ; *************************************************************************** diff --git a/src/hucc/code.c b/src/hucc/code.c index 0535126c..05dffee4 100644 --- a/src/hucc/code.c +++ b/src/hucc/code.c @@ -498,7 +498,7 @@ void gen_code (INS *tmp) case I_MODSP: ot("__modsp"); if (type == T_LITERAL) { - outstr("_sym\t"); + outstr("_goto\t"); outstr((const char *)data); } else { @@ -597,7 +597,7 @@ void gen_code (INS *tmp) case I_DEF: outstr((const char *)data); - outstr(" .equ "); + outstr("\t=\t"); outdec((int)imm_data); nl(); break; @@ -1171,43 +1171,43 @@ void gen_code (INS *tmp) nl(); break; - case X_LDX_WSQ: - ot("__ldx.wsq\t"); + case X_LDX_WS: + ot("__ldx.ws\t"); outdec((int)data); outlocal(tmp->sym); nl(); break; - case X_LDX_BSQ: - ot("__ldx.bsq\t"); + case X_LDX_BS: + ot("__ldx.bs\t"); outdec((int)data); outlocal(tmp->sym); nl(); break; - case X_LDX_USQ: - ot("__ldx.usq\t"); + case X_LDX_US: + ot("__ldx.us\t"); outdec((int)data); outlocal(tmp->sym); nl(); break; - case X_LD2X_WSQ: - ot("__ld2x.wsq\t"); + case X_LDX_WSQ: + ot("__ldx.wsq\t"); outdec((int)data); outlocal(tmp->sym); nl(); break; - case X_LD2X_BSQ: - ot("__ld2x.bsq\t"); + case X_LDX_BSQ: + ot("__ldx.bsq\t"); outdec((int)data); outlocal(tmp->sym); nl(); break; - case X_LD2X_USQ: - ot("__ld2x.usq\t"); + case X_LDX_USQ: + ot("__ldx.usq\t"); outdec((int)data); outlocal(tmp->sym); nl(); @@ -1234,6 +1234,27 @@ void gen_code (INS *tmp) nl(); break; + case X_LD2X_WSQ: + ot("__ld2x.wsq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LD2X_BSQ: + ot("__ld2x.bsq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_LD2X_USQ: + ot("__ld2x.usq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + case X_LDY_WSQ: ot("__ldy.wsq\t"); outdec((int)data); diff --git a/src/hucc/defs.h b/src/hucc/defs.h index 3b097094..d7d482c1 100644 --- a/src/hucc/defs.h +++ b/src/hucc/defs.h @@ -155,14 +155,14 @@ enum ICODE { X_LDX_BMQ, X_LDX_UMQ, - X_LD2X_WMQ, - X_LD2X_BMQ, - X_LD2X_UMQ, - X_LD2X_WM, X_LD2X_BM, X_LD2X_UM, + X_LD2X_WMQ, + X_LD2X_BMQ, + X_LD2X_UMQ, + X_LDY_WMQ, X_LDY_BMQ, X_LDY_UMQ, @@ -190,18 +190,22 @@ enum ICODE { X_LD_BSQ, X_LD_USQ, + X_LDX_WS, + X_LDX_BS, + X_LDX_US, + X_LDX_WSQ, X_LDX_BSQ, X_LDX_USQ, - X_LD2X_WSQ, - X_LD2X_BSQ, - X_LD2X_USQ, - X_LD2X_WS, X_LD2X_BS, X_LD2X_US, + X_LD2X_WSQ, + X_LD2X_BSQ, + X_LD2X_USQ, + X_LDY_WSQ, X_LDY_BSQ, X_LDY_USQ, diff --git a/src/hucc/optimize.c b/src/hucc/optimize.c index 3b9a14f9..1768d404 100644 --- a/src/hucc/optimize.c +++ b/src/hucc/optimize.c @@ -188,14 +188,14 @@ unsigned char icode_flags[] = { /* X_LDX_BMQ */ IS_SBYTE, /* X_LDX_UMQ */ IS_UBYTE, - /* X_LD2X_WMQ */ 0, - /* X_LD2X_BMQ */ IS_SBYTE, - /* X_LD2X_UMQ */ IS_UBYTE, - /* X_LD2X_WM */ 0, /* X_LD2X_BM */ IS_SBYTE, /* X_LD2X_UM */ IS_UBYTE, + /* X_LD2X_WMQ */ 0, + /* X_LD2X_BMQ */ IS_SBYTE, + /* X_LD2X_UMQ */ IS_UBYTE, + /* X_LDY_WMQ */ 0, /* X_LDY_BMQ */ IS_SBYTE, /* X_LDY_UMQ */ IS_UBYTE, @@ -223,18 +223,22 @@ unsigned char icode_flags[] = { /* X_LD_BSQ */ IS_SBYTE + IS_SPREL, /* X_LD_USQ */ IS_UBYTE + IS_SPREL, + /* X_LDX_WS */ IS_SPREL, + /* X_LDX_BS */ IS_SBYTE + IS_SPREL, + /* X_LDX_US */ IS_UBYTE + IS_SPREL, + /* X_LDX_WSQ */ IS_SPREL, /* X_LDX_BSQ */ IS_SBYTE + IS_SPREL, /* X_LDX_USQ */ IS_UBYTE + IS_SPREL, - /* X_LD2X_WSQ */ IS_SPREL, - /* X_LD2X_BSQ */ IS_SBYTE + IS_SPREL, - /* X_LD2X_USQ */ IS_UBYTE + IS_SPREL, - /* X_LD2X_WS */ IS_SPREL, /* X_LD2X_BS */ IS_SBYTE + IS_SPREL, /* X_LD2X_US */ IS_UBYTE + IS_SPREL, + /* X_LD2X_WSQ */ IS_SPREL, + /* X_LD2X_BSQ */ IS_SBYTE + IS_SPREL, + /* X_LD2X_USQ */ IS_UBYTE + IS_SPREL, + /* X_LDY_WSQ */ IS_SPREL, /* X_LDY_BSQ */ IS_SBYTE + IS_SPREL, /* X_LDY_USQ */ IS_UBYTE + IS_SPREL, @@ -1546,7 +1550,7 @@ void push_ins (INS *ins) * __ld.uax symbol * __cmp_w.wt type * - * __push.wr --> __ldx.{w/b/u}sq index + * __push.wr --> __ldx.{w/b/u}s index * __ldx.{w/b/u}sq index __cmp_w.uax type, symbol * __ld.uax symbol * __cmp_w.wt type @@ -1586,6 +1590,15 @@ void push_ins (INS *ins) p[2]->ins_code = X_CMP_WAX; break; case X_LD_UAX: + switch (p[3]->ins_code) { + case X_LDX_WMQ: p[3]->ins_code = X_LDX_WMQ; break; + case X_LDX_BMQ: p[3]->ins_code = X_LDX_BMQ; break; + case X_LDX_UMQ: p[3]->ins_code = X_LDX_UMQ; break; + case X_LDX_WSQ: p[3]->ins_code = X_LDX_WS; break; + case X_LDX_BSQ: p[3]->ins_code = X_LDX_BS; break; + case X_LDX_USQ: p[3]->ins_code = X_LDX_US; break; + default: break; + } p[2]->ins_code = X_CMP_UAX; break; default: break; @@ -2552,6 +2565,15 @@ void push_ins (INS *ins) } break; case X_LD_UAX: + switch (p[3]->ins_code) { + case X_LDX_WMQ: p[3]->ins_code = X_LDX_WMQ; break; + case X_LDX_BMQ: p[3]->ins_code = X_LDX_BMQ; break; + case X_LDX_UMQ: p[3]->ins_code = X_LDX_UMQ; break; + case X_LDX_WSQ: p[3]->ins_code = X_LDX_WS; break; + case X_LDX_BSQ: p[3]->ins_code = X_LDX_BS; break; + case X_LDX_USQ: p[3]->ins_code = X_LDX_US; break; + default: break; + } switch (p[0]->ins_code) { case X_ISUB_WT: p[2]->ins_code = X_ISUB_UAX; break; case I_ADD_WT: p[2]->ins_code = X_ADD_UAX; break; @@ -4254,9 +4276,9 @@ void push_ins (INS *ins) case X_LD_WMQ: index = X_LDX_WMQ; break; case X_LD_BMQ: index = X_LDX_BMQ; break; case X_LD_UMQ: index = X_LDX_UMQ; break; - case X_LD_WSQ: index = X_LDX_WSQ; break; - case X_LD_BSQ: index = X_LDX_BSQ; break; - case X_LD_USQ: index = X_LDX_USQ; break; + case X_LD_WSQ: index = X_LDX_WS; break; + case X_LD_BSQ: index = X_LDX_BS; break; + case X_LD_USQ: index = X_LDX_US; break; default: index = 0; break; } if (index == 0) @@ -4379,9 +4401,9 @@ void push_ins (INS *ins) case X_LDX_WMQ: index = X_LDX_WMQ; break; case X_LDX_BMQ: index = X_LDX_BMQ; break; case X_LDX_UMQ: index = X_LDX_UMQ; break; - case X_LDX_WSQ: index = X_LDX_WSQ; break; - case X_LDX_BSQ: index = X_LDX_BSQ; break; - case X_LDX_USQ: index = X_LDX_USQ; break; + case X_LDX_WSQ: index = X_LDX_WS; break; + case X_LDX_BSQ: index = X_LDX_BS; break; + case X_LDX_USQ: index = X_LDX_US; break; default: index = 0; break; } if (index == 0) From 4bf68df3e0ef3afef093b3b1c1aa54ae50b49a98 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Thu, 23 Jan 2025 19:47:21 -0500 Subject: [PATCH 2/4] Add HuCC index optimization for arrays of structs that are less than 256 bytes long in total. --- include/hucc/hucc-codegen.asm | 138 ++++++++++++++++++++++++++++++++++ src/hucc/code.c | 12 +++ src/hucc/defs.h | 4 +- src/hucc/optimize.c | 36 ++++++++- 4 files changed, 188 insertions(+), 2 deletions(-) diff --git a/include/hucc/hucc-codegen.asm b/include/hucc/hucc-codegen.asm index 4043ca67..1651d01d 100644 --- a/include/hucc/hucc-codegen.asm +++ b/include/hucc/hucc-codegen.asm @@ -5381,6 +5381,35 @@ __asl.wi .macro ; ************** +__asl.uiq .macro + .if (\1 == 8) + asl a + .endif + .if (\1 >= 7) + asl a + .endif + .if (\1 >= 6) + asl a + .endif + .if (\1 >= 5) + asl a + .endif + .if (\1 >= 4) + asl a + .endif + .if (\1 >= 3) + asl a + .endif + .if (\1 >= 2) + asl a + .endif + .if (\1 >= 1) + asl a + .endif + .endm + +; ************** + __asl.wr .macro asl a say @@ -5618,6 +5647,115 @@ __mul.wi .macro .endif .endm +; ************** + +__mul.uiq .macro + .if (\1 == 2) + asl a + .endif + .if (\1 == 3) + sta __temp + asl a + adc __temp + .endif + .if (\1 == 4) + asl a + asl a + .endif + .if (\1 == 5) + sta __temp + asl a + asl a + adc __temp + .endif + .if (\1 == 6) + asl a + sta __temp + asl a + adc __temp + .endif + .if (\1 == 7) + sta __temp + asl a + asl a + asl a + sec + sbc __temp + .endif + .if (\1 == 8) + asl a + asl a + asl a + .endif + .if (\1 == 9) + sta __temp + asl a + asl a + asl a + adc __temp + .endif + .if (\1 == 10) + asl a + sta __temp + asl a + asl a + adc __temp + .endif + .if (\1 == 11) + sta.l __temp + asl a + sta.h __temp + asl a + asl a + adc.l __temp + adc.h __temp + .endif + .if (\1 == 12) + asl a + asl a + sta __temp + asl a + adc __temp + .endif + .if (\1 == 13) + sta.l __temp + asl a + asl a + sta.h __temp + asl a + adc.l __temp + adc.h __temp + .endif + .if (\1 == 14) + asl a + sta __temp + asl a + asl a + asl a + sec + sbc __temp + .endif + .if (\1 == 15) + sta __temp + asl a + asl a + asl a + asl a + sec + sbc __temp + .endif + .if (\1 == 16) + asl a + asl a + asl a + asl a + .endif + .if (\1 >= 17) + ldy #\1 + jsr __muluchar + .endif + .endm + ; ************** ; Y:A = stacked-value / Y:A diff --git a/src/hucc/code.c b/src/hucc/code.c index 05dffee4..85b5b754 100644 --- a/src/hucc/code.c +++ b/src/hucc/code.c @@ -2455,6 +2455,12 @@ void gen_code (INS *tmp) nl(); break; + case I_ASL_UIQ: + ot("__asl.uiq\t"); + out_type(type, data); + nl(); + break; + case I_ASL_WR: ol("__asl.wr"); break; @@ -2495,6 +2501,12 @@ void gen_code (INS *tmp) nl(); break; + case I_MUL_UIQ: + ot("__mul.uiq\t"); + out_type(type, data); + nl(); + break; + case I_SDIV_WT: ol("__sdiv.wt"); break; diff --git a/src/hucc/defs.h b/src/hucc/defs.h index d7d482c1..ec21b5f4 100644 --- a/src/hucc/defs.h +++ b/src/hucc/defs.h @@ -448,9 +448,10 @@ enum ICODE { X_OR_WAX, X_OR_UAX, + I_ASL_WR, I_ASL_WT, I_ASL_WI, - I_ASL_WR, + I_ASL_UIQ, I_ASR_WT, I_ASR_WI, @@ -461,6 +462,7 @@ enum ICODE { I_MUL_WT, I_MUL_WI, + I_MUL_UIQ, I_SDIV_WT, I_SDIV_WI, diff --git a/src/hucc/optimize.c b/src/hucc/optimize.c index 1768d404..f3fe1600 100644 --- a/src/hucc/optimize.c +++ b/src/hucc/optimize.c @@ -481,9 +481,10 @@ unsigned char icode_flags[] = { /* X_OR_WAX */ IS_USEPR, /* X_OR_UAX */ IS_USEPR, + /* I_ASL_WR */ IS_USEPR, /* I_ASL_WT */ IS_USEPR + IS_POPWT, /* I_ASL_WI */ IS_USEPR, - /* I_ASL_WR */ IS_USEPR, + /* I_ASL_UIQ */ IS_USEPR, /* I_ASR_WT */ IS_USEPR + IS_POPWT, /* I_ASR_WI */ IS_USEPR, @@ -494,6 +495,7 @@ unsigned char icode_flags[] = { /* I_MUL_WT */ IS_USEPR + IS_POPWT, /* I_MUL_WI */ IS_USEPR, + /* I_MUL_UIQ */ IS_USEPR, /* I_SDIV_WT */ IS_USEPR + IS_POPWT, /* I_SDIV_WI */ IS_USEPR, @@ -3426,6 +3428,38 @@ void push_ins (INS *ins) remove = 0; } + /* + * __mul.wi n --> __mul.uiq n + * __index.{w/u}r array __index.{w/u}r array + * + * __asl.wi n --> __asl.uiq n + * __index.{w/u}r array __index.{w/u}r array + * + * Index optimizations for access to an array of structs. + */ + else if + ((p[0]->ins_code == X_INDEX_WR || + p[0]->ins_code == X_INDEX_UR) && + (p[1]->ins_code == I_ASL_WI || + p[1]->ins_code == I_MUL_WI) + ) { + /* replace code */ + if (p[1]->ins_code == I_ASL_WI) + p[1]->ins_code = I_ASL_UIQ; + else + p[1]->ins_code = I_MUL_UIQ; + switch (p[2]->ins_code) { + case I_LD_WM: p[2]->ins_code = X_LD_WMQ; break; + case I_LD_BM: p[2]->ins_code = X_LD_BMQ; break; + case I_LD_UM: p[2]->ins_code = X_LD_UMQ; break; + case X_LD_WS: p[2]->ins_code = X_LD_WSQ; break; + case X_LD_BS: p[2]->ins_code = X_LD_BSQ; break; + case X_LD_US: p[2]->ins_code = X_LD_USQ; break; + default: break; + } + remove = 0; + } + /* * __ld.{w/b/u}m symbol --> __ld2x.{w/b/u}mq * __ld.war array __ld.wax array From 747149ebb2727ad2b84e6acac4c98d6030dd0398 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Thu, 23 Jan 2025 20:42:22 -0500 Subject: [PATCH 3/4] Apply the array of structs optimization to more cases (such as loading). --- src/hucc/optimize.c | 82 +++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/src/hucc/optimize.c b/src/hucc/optimize.c index f3fe1600..9a5f2933 100644 --- a/src/hucc/optimize.c +++ b/src/hucc/optimize.c @@ -3428,38 +3428,6 @@ void push_ins (INS *ins) remove = 0; } - /* - * __mul.wi n --> __mul.uiq n - * __index.{w/u}r array __index.{w/u}r array - * - * __asl.wi n --> __asl.uiq n - * __index.{w/u}r array __index.{w/u}r array - * - * Index optimizations for access to an array of structs. - */ - else if - ((p[0]->ins_code == X_INDEX_WR || - p[0]->ins_code == X_INDEX_UR) && - (p[1]->ins_code == I_ASL_WI || - p[1]->ins_code == I_MUL_WI) - ) { - /* replace code */ - if (p[1]->ins_code == I_ASL_WI) - p[1]->ins_code = I_ASL_UIQ; - else - p[1]->ins_code = I_MUL_UIQ; - switch (p[2]->ins_code) { - case I_LD_WM: p[2]->ins_code = X_LD_WMQ; break; - case I_LD_BM: p[2]->ins_code = X_LD_BMQ; break; - case I_LD_UM: p[2]->ins_code = X_LD_UMQ; break; - case X_LD_WS: p[2]->ins_code = X_LD_WSQ; break; - case X_LD_BS: p[2]->ins_code = X_LD_BSQ; break; - case X_LD_US: p[2]->ins_code = X_LD_USQ; break; - default: break; - } - remove = 0; - } - /* * __ld.{w/b/u}m symbol --> __ld2x.{w/b/u}mq * __ld.war array __ld.wax array @@ -3539,6 +3507,56 @@ void push_ins (INS *ins) } } + /* + * __mul.wi n --> __mul.uiq n + * __index.{w/u}r array __index.{w/u}r array + * + * __asl.wi n --> __asl.uiq n + * __index.{w/u}r array __index.{w/u}r array + * + * __mul.wi n --> __mul.uiq n + * __ld.{w/b/u}ar array __ld.{w/b/u}ar array + * + * __asl.wi n --> __asl.uiq n + * __ld.{w/b/u}ar array __ld.{w/b/u}ar array + * + * __mul.wi n --> __mul.uiq n + * __ldp.{w/b/u}ar array __ldp.{w/b/u}ar array + * + * __asl.wi n --> __asl.uiq n + * __ldp.{w/b/u}ar array __ldp.{w/b/u}ar array + * + * Index optimizations for access to an array of structs. + */ + else if + ((p[0]->ins_code == X_INDEX_WR || + p[0]->ins_code == X_INDEX_UR || + p[0]->ins_code == X_LD_WAR || + p[0]->ins_code == X_LD_BAR || + p[0]->ins_code == X_LD_UAR || + p[0]->ins_code == X_LDP_WAR || + p[0]->ins_code == X_LDP_BAR || + p[0]->ins_code == X_LDP_UAR) && + (p[1]->ins_code == I_ASL_WI || + p[1]->ins_code == I_MUL_WI) + ) { + /* replace code */ + if (p[1]->ins_code == I_ASL_WI) + p[1]->ins_code = I_ASL_UIQ; + else + p[1]->ins_code = I_MUL_UIQ; + switch (p[2]->ins_code) { + case I_LD_WM: p[2]->ins_code = X_LD_WMQ; break; + case I_LD_BM: p[2]->ins_code = X_LD_BMQ; break; + case I_LD_UM: p[2]->ins_code = X_LD_UMQ; break; + case X_LD_WS: p[2]->ins_code = X_LD_WSQ; break; + case X_LD_BS: p[2]->ins_code = X_LD_BSQ; break; + case X_LD_US: p[2]->ins_code = X_LD_USQ; break; + default: break; + } + remove = 0; + } + #if 0 /* * __ld.{w/b/u}m symbol --> __ldy.{w/b/u}mq From 68c34b9ff8f40e9cd86cf42744a0e80511380682 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Sun, 26 Jan 2025 10:28:31 -0500 Subject: [PATCH 4/4] Add optimized HuCC code macros for "+=", "-=", "&=", "^=" and "|=" now that the rescheduler has made them easily detectable in the peephole window. Add extra optimizations of "+=" and "-=" with a constant, so that the generated code looks pretty-much like an asm programmer would write. --- include/hucc/hucc-codegen.asm | 559 ++++++++++++++++++++++++++++++++- src/hucc/code.c | 506 ++++++++++++++++++++++++++++++ src/hucc/defs.h | 88 ++++++ src/hucc/expr.c | 1 - src/hucc/optimize.c | 568 +++++++++++++++++++++++++++++++++- 5 files changed, 1704 insertions(+), 18 deletions(-) diff --git a/include/hucc/hucc-codegen.asm b/include/hucc/hucc-codegen.asm index 1651d01d..1feef283 100644 --- a/include/hucc/hucc-codegen.asm +++ b/include/hucc/hucc-codegen.asm @@ -4237,7 +4237,7 @@ __st.wpiq .macro __st.upiq .macro sta.l __ptr sty.h __ptr - lda #\1 + lda.l #\1 sta [__ptr] .endm @@ -4299,6 +4299,43 @@ __st.uatq .macro sta \1, x .endm +; ************** + +__st.watiq .macro + plx + .if (\?1 != ARG_ABS) + lda.l #\1 + sta.l \2, x + lda.h #\1 + sta.h \2, x + .else + .if (\1 & $00FF) + lda.l #\1 + sta.l \2, x + .else + stz.l \2, x + .endif + .if (\1 & $FF00) + lda.h #\1 + sta.h \2, x + .else + stz.h \2, x + .endif + .endif + .endm + +; ************** + +__st.uatiq .macro + plx + .if (\1 != 0) + lda.l #\1 + sta \2, x + .else + stz \2, x + .endif + .endm + ; ************** ; special store for when array writes are optimized ; this balances the cpu stack after an __index.wr or __ldp.war @@ -4338,6 +4375,41 @@ __st.uaxq .macro ; ************** +__st.waxiq .macro + .if (\?1 != ARG_ABS) + lda.l #\1 + sta.l \2, x + lda.h #\1 + sta.h \2, x + .else + .if (\1 & $00FF) + lda.l #\1 + sta.l \2, x + .else + stz.l \2, x + .endif + .if (\1 & $FF00) + lda.h #\1 + sta.h \2, x + .else + stz.h \2, x + .endif + .endif + .endm + +; ************** + +__st.uaxiq .macro + .if (\1 != 0) + lda.l #\1 + sta \2, x + .else + stz \2, x + .endif + .endm + +; ************** + __st.wsiq .macro ldx <__sp .if (\?1 != ARG_ABS) @@ -5883,6 +5955,26 @@ __add_st.umq .macro ; ************** +__add_st.wpq .macro + clc + adc [\1] + sta [\1] + tya + ldy #1 + adc [\1], y + sta [\1], y + .endm + +; ************** + +__add_st.upq .macro + clc + adc [\1] + sta [\1] + .endm + +; ************** + __add_st.wsq .macro ; __STACK ldx <__sp clc @@ -5966,6 +6058,29 @@ __isub_st.umq .macro sta \1 .endm +; ************** + +__isub_st.wpq .macro + sec + eor #$FF + adc [\1] + sta [\1] + tya + ldy #1 + eor #$FF + adc [\1], y + sta [\1], y + .endm + +; ************** + +__isub_st.upq .macro + sec + eor #$FF + adc [\1] + sta [\1] + .endm + ; ************** ; Y:A = memory - Y:A @@ -6061,6 +6176,24 @@ __and_st.umq .macro ; ************** +__and_st.wpq .macro + and [\1] + sta [\1] + tya + ldy #1 + and [\1], y + sta [\1], y + .endm + +; ************** + +__and_st.upq .macro + and [\1] + sta [\1] + .endm + +; ************** + __and_st.wsq .macro ldx <__sp and.l <__stack + \1, x @@ -6133,6 +6266,24 @@ __eor_st.umq .macro ; ************** +__eor_st.wpq .macro + eor [\1] + sta [\1] + tya + ldy #1 + eor [\1], y + sta [\1], y + .endm + +; ************** + +__eor_st.upq .macro + eor [\1] + sta [\1] + .endm + +; ************** + __eor_st.wsq .macro ldx <__sp eor.l <__stack + \1, x @@ -6205,6 +6356,24 @@ __or_st.umq .macro ; ************** +__or_st.wpq .macro + or [\1] + sta [\1] + tya + ldy #1 + or [\1], y + sta [\1], y + .endm + +; ************** + +__or_st.upq .macro + or [\1] + sta [\1] + .endm + +; ************** + __or_st.wsq .macro ldx <__sp ora.l <__stack + \1, x @@ -6258,6 +6427,394 @@ __or_st.uaxq .macro sta \1, x .endm +; ************** + +__add_st.wmiq .macro + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + inc.l \2 + bne !+ + inc.h \2 +!: + .else + .if ((\?1 == ARG_ABS) && ((\1) >= 0) && ((\1) < 256)) + clc + lda.l \2 + adc.l #\1 + sta.l \2 + bcc !+ + inc.h \2 +!: + .else + clc + lda.l \2 + adc.l #\1 + sta.l \2 + lda.h \2 + adc.h #\1 + sta.h \2 + .endif + .endif + .endm + +; ************** + +__add_st.umiq .macro + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + inc \2 + .else + clc + lda \2 + adc #\1 + sta \2 + .endif + .endm + +; ************** + +__add_st.wpiq .macro + clc + lda [\2] + adc.l #\1 + sta [\2] + ldy #1 + lda [\2], y + adc.h #\1 + sta [\2], y + .endm + +; ************** + +__add_st.upiq .macro + clc + lda [\2] + adc #\1 + sta [\2] + .endm + +; ************** + +__add_st.wsiq .macro ; __STACK + ldx <__sp + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + inc.l <__stack + \2, x + bne !+ + inc.h <__stack + \2, x +!: + .else + .if ((\?1 == ARG_ABS) && ((\1) >= 0) && ((\1) < 256)) + clc + lda.l <__stack + \2, x + adc.l #\1 + sta.l <__stack + \2, x + bcc !+ + inc.h <__stack + \2, x +!: + .else + clc + lda.l <__stack + \2, x + adc.l #\1 + sta.l <__stack + \2, x + lda.h <__stack + \2, x + adc.h #\1 + sta.h <__stack + \2, x + .endif + .endif + .endm + +; ************** + +__add_st.usiq .macro ; __STACK + ldx <__sp + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + inc <__stack + \2, x + .else + clc + lda <__stack + \2, x + adc #\1 + sta <__stack + \2, x + .endif + .endm + +; ************** + +__add_st.watiq .macro ; __STACK + plx + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + inc.l \2, x + bne !+ + inc.h \2, x +!: + .else + .if ((\?1 == ARG_ABS) && ((\1) >= 0) && ((\1) < 256)) + clc + lda.l \2, x + adc.l #\1 + sta.l \2, x + bcc !+ + inc.h \2, x +!: + .else + clc + lda.l \2, x + adc.l #\1 + sta.l \2, x + lda.h \2, x + adc.h #\1 + sta.h \2, x + .endif + .endif + .endm + +; ************** + +__add_st.uatiq .macro ; __STACK + plx + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + inc \2, x + .else + clc + lda \2, x + adc #\1 + sta \2, x + .endif + .endm + +; ************** + +__add_st.waxiq .macro ; __STACK + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + inc.l \2, x + bne !+ + inc.h \2, x +!: + .else + .if ((\?1 == ARG_ABS) && ((\1) >= 0) && ((\1) < 256)) + clc + lda.l \2, x + adc.l #\1 + sta.l \2, x + bcc !+ + inc.h \2, x +!: + .else + clc + lda.l \2, x + adc.l #\1 + sta.l \2, x + lda.h \2, x + adc.h #\1 + sta.h \2, x + .endif + .endif + .endm + +; ************** + +__add_st.uaxiq .macro ; __STACK + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + inc \2, x + .else + clc + lda \2, x + adc #\1 + sta \2, x + .endif + .endm + +; ************** + +__sub_st.wmiq .macro + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + lda.l \2 + bne !+ + dec.h \2 +!: dec.l \2 + .else + .if ((\?1 == ARG_ABS) && ((\1) >= 0) && ((\1) < 256)) + sec + lda.l \2 + sbc.l #\1 + sta.l \2 + bcs !+ + dec.h \2 +!: + .else + sec + lda.l \2 + sbc.l #\1 + sta.l \2 + lda.h \2 + sbc.h #\1 + sta.h \2 + .endif + .endif + .endm + +; ************** + +__sub_st.umiq .macro + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + dec \2 + .else + sec + lda \2 + sbc #\1 + sta \2 + .endif + .endm + +; ************** + +__sub_st.wpiq .macro + sec + lda [\2] + sbc.l #\1 + sta [\2] + ldy #1 + lda [\2], y + sbc.h #\1 + sta [\2], y + .endm + +; ************** + +__sub_st.upiq .macro + sec + lda [\2] + sbc #\1 + sta [\2] + .endm + +; ************** + +__sub_st.wsiq .macro ; __STACK + ldx <__sp + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + lda.l <__stack + \2, x + bne !+ + dec.h <__stack + \2, x +!: dec.l <__stack + \2, x + .else + .if ((\?1 == ARG_ABS) && ((\1) >= 0) && ((\1) < 256)) + sec + lda.l <__stack + \2, x + sbc.l #\1 + sta.l <__stack + \2, x + bcs !+ + dec.h <__stack + \2, x +!: + .else + sec + lda.l <__stack + \2, x + sbc.l #\1 + sta.l <__stack + \2, x + lda.h <__stack + \2, x + sbc.h #\1 + sta.h <__stack + \2, x + .endif + .endif + .endm + +; ************** + +__sub_st.usiq .macro ; __STACK + ldx <__sp + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + dec <__stack + \2, x + .else + sec + lda <__stack + \2, x + sbc #\1 + sta <__stack + \2, x + .endif + .endm + +; ************** + +__sub_st.watiq .macro ; __STACK + plx + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + lda.l \2, x + bne !+ + dec.h \2, x +!: dec.l \2, x + .else + .if ((\?1 == ARG_ABS) && ((\1) >= 0) && ((\1) < 256)) + sec + lda.l \2, x + sbc.l #\1 + sta.l \2, x + bcs !+ + dec.h \2, x +!: + .else + sec + lda.l \2, x + sbc.l #\1 + sta.l \2, x + lda.h \2, x + sbc.h #\1 + sta.h \2, x + .endif + .endif + .endm + +; ************** + +__sub_st.uatiq .macro ; __STACK + plx + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + dec \2, x + .else + sec + lda \2, x + sbc #\1 + sta \2, x + .endif + .endm + +; ************** + +__sub_st.waxiq .macro ; __STACK + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + lda.l \2, x + bne !+ + dec.h \2, x +!: dec.l \2, x + .else + .if ((\?1 == ARG_ABS) && ((\1) >= 0) && ((\1) < 256)) + sec + lda.l \2, x + sbc.l #\1 + sta.l \2, x + bcs !+ + dec.h \2, x +!: + .else + sec + lda.l \2, x + sbc.l #\1 + sta.l \2, x + lda.h \2, x + sbc.h #\1 + sta.h \2, x + .endif + .endif + .endm + +; ************** + +__sub_st.uaxiq .macro ; __STACK + .if ((\?1 == ARG_ABS) && ((\1) == 1)) + dec \2, x + .else + sec + lda \2, x + sbc #\1 + sta \2, x + .endif + .endm + ; *************************************************************************** diff --git a/src/hucc/code.c b/src/hucc/code.c index 85b5b754..0f000aec 100644 --- a/src/hucc/code.c +++ b/src/hucc/code.c @@ -1963,6 +1963,22 @@ void gen_code (INS *tmp) nl(); break; + case X_ST_WATIQ: + ot("__st.watiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_type(type, data); + nl(); + break; + + case X_ST_UATIQ: + ot("__st.uatiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_type(type, data); + nl(); + break; + case X_ST_WAX: ot("__st.wax\t"); out_type(type, data); @@ -1987,6 +2003,22 @@ void gen_code (INS *tmp) nl(); break; + case X_ST_WAXIQ: + ot("__st.waxiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_type(type, data); + nl(); + break; + + case X_ST_UAXIQ: + ot("__st.uaxiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_type(type, data); + nl(); + break; + /* i-codes for extending a byte to a word */ case I_EXT_BR: @@ -2079,6 +2111,150 @@ void gen_code (INS *tmp) nl(); break; + case X_ADD_ST_WMQ: + ot("__add_st.wmq\t"); + out_addr(type, data); + nl(); + break; + + case X_ADD_ST_UMQ: + ot("__add_st.umq\t"); + out_addr(type, data); + nl(); + break; + + case X_ADD_ST_WPQ: + ot("__add_st.wpq\t"); + out_addr(type, data); + nl(); + break; + + case X_ADD_ST_UPQ: + ot("__add_st.upq\t"); + out_addr(type, data); + nl(); + break; + + case X_ADD_ST_WSQ: + ot("__add_st.wsq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_ADD_ST_USQ: + ot("__add_st.usq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_ADD_ST_WATQ: + ot("__add_st.watq\t"); + out_addr(type, data); + nl(); + break; + + case X_ADD_ST_UATQ: + ot("__add_st.uatq\t"); + out_addr(type, data); + nl(); + break; + + case X_ADD_ST_WAXQ: + ot("__add_st.waxq\t"); + out_addr(type, data); + nl(); + break; + + case X_ADD_ST_UAXQ: + ot("__add_st.uaxq\t"); + out_addr(type, data); + nl(); + break; + + case X_ADD_ST_WMIQ: + ot("__add_st.wmiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_type(type, data); + nl(); + break; + + case X_ADD_ST_UMIQ: + ot("__add_st.umiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_type(type, data); + nl(); + break; + + case X_ADD_ST_WPIQ: + ot("__add_st.wpiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_addr(type, data); + nl(); + break; + + case X_ADD_ST_UPIQ: + ot("__add_st.upiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_addr(type, data); + nl(); + break; + + case X_ADD_ST_WSIQ: + ot("__add_st.wsiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_ADD_ST_USIQ: + ot("__add_st.usiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_ADD_ST_WATIQ: + ot("__add_st.watiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_addr(type, data); + nl(); + break; + + case X_ADD_ST_UATIQ: + ot("__add_st.uatiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_addr(type, data); + nl(); + break; + + case X_ADD_ST_WAXIQ: + ot("__add_st.waxiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_addr(type, data); + nl(); + break; + + case X_ADD_ST_UAXIQ: + ot("__add_st.uaxiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_addr(type, data); + nl(); + break; + case I_SUB_WT: ol("__sub.wt"); break; @@ -2151,6 +2327,88 @@ void gen_code (INS *tmp) nl(); break; + case X_SUB_ST_WMIQ: + ot("__sub_st.wmiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_type(type, data); + nl(); + break; + + case X_SUB_ST_UMIQ: + ot("__sub_st.umiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_type(type, data); + nl(); + break; + + case X_SUB_ST_WPIQ: + ot("__sub_st.wpiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_addr(type, data); + nl(); + break; + + case X_SUB_ST_UPIQ: + ot("__sub_st.upiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_addr(type, data); + nl(); + break; + + case X_SUB_ST_WSIQ: + ot("__sub_st.wsiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_SUB_ST_USIQ: + ot("__sub_st.usiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_SUB_ST_WATIQ: + ot("__sub_st.watiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_addr(type, data); + nl(); + break; + + case X_SUB_ST_UATIQ: + ot("__sub_st.uatiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_addr(type, data); + nl(); + break; + + case X_SUB_ST_WAXIQ: + ot("__sub_st.waxiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_addr(type, data); + nl(); + break; + + case X_SUB_ST_UAXIQ: + ot("__sub_st.uaxiq\t"); + out_type(imm_type, imm_data); + outstr(", "); + out_addr(type, data); + nl(); + break; + case X_ISUB_WT: ol("__isub.wt"); break; @@ -2223,6 +2481,68 @@ void gen_code (INS *tmp) nl(); break; + case X_ISUB_ST_WMQ: + ot("__isub_st.wmq\t"); + out_addr(type, data); + nl(); + break; + + case X_ISUB_ST_UMQ: + ot("__isub_st.umq\t"); + out_addr(type, data); + nl(); + break; + + case X_ISUB_ST_WPQ: + ot("__isub_st.wpq\t"); + out_addr(type, data); + nl(); + break; + + case X_ISUB_ST_UPQ: + ot("__isub_st.upq\t"); + out_addr(type, data); + nl(); + break; + + case X_ISUB_ST_WSQ: + ot("__isub_st.wsq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_ISUB_ST_USQ: + ot("__isub_st.usq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_ISUB_ST_WATQ: + ot("__isub_st.watq\t"); + out_addr(type, data); + nl(); + break; + + case X_ISUB_ST_UATQ: + ot("__isub_st.uatq\t"); + out_addr(type, data); + nl(); + break; + + case X_ISUB_ST_WAXQ: + ot("__isub_st.waxq\t"); + out_addr(type, data); + nl(); + break; + + case X_ISUB_ST_UAXQ: + ot("__isub_st.uaxq\t"); + out_addr(type, data); + nl(); + break; + case I_AND_WT: ol("__and.wt"); break; @@ -2301,6 +2621,68 @@ void gen_code (INS *tmp) nl(); break; + case X_AND_ST_WMQ: + ot("__and_st.wmq\t"); + out_addr(type, data); + nl(); + break; + + case X_AND_ST_UMQ: + ot("__and_st.umq\t"); + out_addr(type, data); + nl(); + break; + + case X_AND_ST_WPQ: + ot("__and_st.wpq\t"); + out_addr(type, data); + nl(); + break; + + case X_AND_ST_UPQ: + ot("__and_st.upq\t"); + out_addr(type, data); + nl(); + break; + + case X_AND_ST_WSQ: + ot("__and_st.wsq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_AND_ST_USQ: + ot("__and_st.usq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_AND_ST_WATQ: + ot("__and_st.watq\t"); + out_addr(type, data); + nl(); + break; + + case X_AND_ST_UATQ: + ot("__and_st.uatq\t"); + out_addr(type, data); + nl(); + break; + + case X_AND_ST_WAXQ: + ot("__and_st.waxq\t"); + out_addr(type, data); + nl(); + break; + + case X_AND_ST_UAXQ: + ot("__and_st.uaxq\t"); + out_addr(type, data); + nl(); + break; + case I_EOR_WT: ol("__eor.wt"); break; @@ -2373,6 +2755,68 @@ void gen_code (INS *tmp) nl(); break; + case X_EOR_ST_WMQ: + ot("__eor_st.wmq\t"); + out_addr(type, data); + nl(); + break; + + case X_EOR_ST_UMQ: + ot("__eor_st.umq\t"); + out_addr(type, data); + nl(); + break; + + case X_EOR_ST_WPQ: + ot("__eor_st.wpq\t"); + out_addr(type, data); + nl(); + break; + + case X_EOR_ST_UPQ: + ot("__eor_st.upq\t"); + out_addr(type, data); + nl(); + break; + + case X_EOR_ST_WSQ: + ot("__eor_st.wsq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_EOR_ST_USQ: + ot("__eor_st.usq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_EOR_ST_WATQ: + ot("__eor_st.watq\t"); + out_addr(type, data); + nl(); + break; + + case X_EOR_ST_UATQ: + ot("__eor_st.uatq\t"); + out_addr(type, data); + nl(); + break; + + case X_EOR_ST_WAXQ: + ot("__eor_st.waxq\t"); + out_addr(type, data); + nl(); + break; + + case X_EOR_ST_UAXQ: + ot("__eor_st.uaxq\t"); + out_addr(type, data); + nl(); + break; + case I_OR_WT: ol("__or.wt"); break; @@ -2445,6 +2889,68 @@ void gen_code (INS *tmp) nl(); break; + case X_OR_ST_WMQ: + ot("__or_st.wmq\t"); + out_addr(type, data); + nl(); + break; + + case X_OR_ST_UMQ: + ot("__or_st.umq\t"); + out_addr(type, data); + nl(); + break; + + case X_OR_ST_WPQ: + ot("__or_st.wpq\t"); + out_addr(type, data); + nl(); + break; + + case X_OR_ST_UPQ: + ot("__or_st.upq\t"); + out_addr(type, data); + nl(); + break; + + case X_OR_ST_WSQ: + ot("__or_st.wsq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_OR_ST_USQ: + ot("__or_st.usq\t"); + outdec((int)data); + outlocal(tmp->sym); + nl(); + break; + + case X_OR_ST_WATQ: + ot("__or_st.watq\t"); + out_addr(type, data); + nl(); + break; + + case X_OR_ST_UATQ: + ot("__or_st.uatq\t"); + out_addr(type, data); + nl(); + break; + + case X_OR_ST_WAXQ: + ot("__or_st.waxq\t"); + out_addr(type, data); + nl(); + break; + + case X_OR_ST_UAXQ: + ot("__or_st.uaxq\t"); + out_addr(type, data); + nl(); + break; + case I_ASL_WT: ol("__asl.wt"); break; diff --git a/src/hucc/defs.h b/src/hucc/defs.h index ec21b5f4..1029bb2a 100644 --- a/src/hucc/defs.h +++ b/src/hucc/defs.h @@ -354,10 +354,15 @@ enum ICODE { X_ST_UAT, X_ST_WATQ, X_ST_UATQ, + X_ST_WATIQ, + X_ST_UATIQ, + X_ST_WAX, X_ST_UAX, X_ST_WAXQ, X_ST_UAXQ, + X_ST_WAXIQ, + X_ST_UAXIQ, /* i-codes for extending the primary register */ @@ -371,6 +376,7 @@ enum ICODE { I_ADD_WT, I_ADD_WI, + X_ADD_WM, X_ADD_UM, X_ADD_WP, @@ -382,8 +388,31 @@ enum ICODE { X_ADD_WAX, X_ADD_UAX, + X_ADD_ST_WMQ, + X_ADD_ST_UMQ, + X_ADD_ST_WPQ, + X_ADD_ST_UPQ, + X_ADD_ST_WSQ, + X_ADD_ST_USQ, + X_ADD_ST_WATQ, + X_ADD_ST_UATQ, + X_ADD_ST_WAXQ, + X_ADD_ST_UAXQ, + + X_ADD_ST_WMIQ, + X_ADD_ST_UMIQ, + X_ADD_ST_WPIQ, + X_ADD_ST_UPIQ, + X_ADD_ST_WSIQ, + X_ADD_ST_USIQ, + X_ADD_ST_WATIQ, + X_ADD_ST_UATIQ, + X_ADD_ST_WAXIQ, + X_ADD_ST_UAXIQ, + I_SUB_WT, I_SUB_WI, + X_SUB_WM, X_SUB_UM, X_SUB_WP, @@ -395,8 +424,20 @@ enum ICODE { X_SUB_WAX, X_SUB_UAX, + X_SUB_ST_WMIQ, + X_SUB_ST_UMIQ, + X_SUB_ST_WPIQ, + X_SUB_ST_UPIQ, + X_SUB_ST_WSIQ, + X_SUB_ST_USIQ, + X_SUB_ST_WATIQ, + X_SUB_ST_UATIQ, + X_SUB_ST_WAXIQ, + X_SUB_ST_UAXIQ, + X_ISUB_WT, X_ISUB_WI, + X_ISUB_WM, X_ISUB_UM, X_ISUB_WP, @@ -408,9 +449,21 @@ enum ICODE { X_ISUB_WAX, X_ISUB_UAX, + X_ISUB_ST_WMQ, + X_ISUB_ST_UMQ, + X_ISUB_ST_WPQ, + X_ISUB_ST_UPQ, + X_ISUB_ST_WSQ, + X_ISUB_ST_USQ, + X_ISUB_ST_WATQ, + X_ISUB_ST_UATQ, + X_ISUB_ST_WAXQ, + X_ISUB_ST_UAXQ, + I_AND_WT, X_AND_WI, X_AND_UIQ, + X_AND_WM, X_AND_UM, X_AND_WP, @@ -422,8 +475,20 @@ enum ICODE { X_AND_WAX, X_AND_UAX, + X_AND_ST_WMQ, + X_AND_ST_UMQ, + X_AND_ST_WPQ, + X_AND_ST_UPQ, + X_AND_ST_WSQ, + X_AND_ST_USQ, + X_AND_ST_WATQ, + X_AND_ST_UATQ, + X_AND_ST_WAXQ, + X_AND_ST_UAXQ, + I_EOR_WT, X_EOR_WI, + X_EOR_WM, X_EOR_UM, X_EOR_WP, @@ -435,8 +500,20 @@ enum ICODE { X_EOR_WAX, X_EOR_UAX, + X_EOR_ST_WMQ, + X_EOR_ST_UMQ, + X_EOR_ST_WPQ, + X_EOR_ST_UPQ, + X_EOR_ST_WSQ, + X_EOR_ST_USQ, + X_EOR_ST_WATQ, + X_EOR_ST_UATQ, + X_EOR_ST_WAXQ, + X_EOR_ST_UAXQ, + I_OR_WT, X_OR_WI, + X_OR_WM, X_OR_UM, X_OR_WP, @@ -448,6 +525,17 @@ enum ICODE { X_OR_WAX, X_OR_UAX, + X_OR_ST_WMQ, + X_OR_ST_UMQ, + X_OR_ST_WPQ, + X_OR_ST_UPQ, + X_OR_ST_WSQ, + X_OR_ST_USQ, + X_OR_ST_WATQ, + X_OR_ST_UATQ, + X_OR_ST_WAXQ, + X_OR_ST_UAXQ, + I_ASL_WR, I_ASL_WT, I_ASL_WI, diff --git a/src/hucc/expr.c b/src/hucc/expr.c index e4fb6e04..6990718d 100644 --- a/src/hucc/expr.c +++ b/src/hucc/expr.c @@ -73,7 +73,6 @@ int expression_ex (LVALUE *lval, int comma, int norval) * ubyte | sword sword ubyte uword * uword | uword uword uword uword */ - static int is_unsigned (LVALUE *lval) { /* C promotes operations on an unsigned char diff --git a/src/hucc/optimize.c b/src/hucc/optimize.c index 9a5f2933..78e61952 100644 --- a/src/hucc/optimize.c +++ b/src/hucc/optimize.c @@ -383,14 +383,19 @@ unsigned char icode_flags[] = { /* X_INDEX_WR */ IS_USEPR + IS_PUSHWT, /* X_INDEX_UR */ IS_USEPR + IS_PUSHWT, - /* X_ST_WAT */ IS_USEPR + IS_POPWT + IS_STORE, - /* X_ST_UAT */ IS_USEPR + IS_POPWT + IS_STORE, - /* X_ST_WATQ */ IS_USEPR + IS_POPWT + IS_SHORT + IS_STORE, - /* X_ST_UATQ */ IS_USEPR + IS_POPWT + IS_SHORT + IS_STORE, + /* X_ST_WAT */ IS_USEPR + IS_STORE + IS_POPWT, + /* X_ST_UAT */ IS_USEPR + IS_STORE + IS_POPWT, + /* X_ST_WATQ */ IS_USEPR + IS_STORE + IS_POPWT + IS_SHORT, + /* X_ST_UATQ */ IS_USEPR + IS_STORE + IS_POPWT + IS_SHORT, + /* X_ST_WATIQ */ IS_USEPR + IS_STORE + IS_POPWT + IS_SHORT, + /* X_ST_UATIQ */ IS_USEPR + IS_STORE + IS_POPWT + IS_SHORT, + /* X_ST_WAX */ IS_USEPR + IS_STORE, /* X_ST_UAX */ IS_USEPR + IS_STORE, /* X_ST_WAXQ */ IS_USEPR + IS_STORE + IS_SHORT, /* X_ST_UAXQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_ST_WAXIQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_ST_UAXIQ */ IS_USEPR + IS_STORE + IS_SHORT, // i-codes for extending the primary register @@ -404,6 +409,7 @@ unsigned char icode_flags[] = { /* I_ADD_WT */ IS_USEPR + IS_POPWT, /* I_ADD_WI */ IS_USEPR, + /* X_ADD_WM */ IS_USEPR, /* X_ADD_UM */ IS_USEPR, /* X_ADD_WP */ IS_USEPR, @@ -415,8 +421,31 @@ unsigned char icode_flags[] = { /* X_ADD_WAX */ IS_USEPR, /* X_ADD_UAX */ IS_USEPR, + /* X_ADD_ST_WMQ */ IS_USEPR + IS_STORE, + /* X_ADD_ST_UMQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_ADD_ST_WPQ */ IS_USEPR + IS_STORE, + /* X_ADD_ST_UPQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_ADD_ST_WSQ */ IS_USEPR + IS_STORE + IS_SPREL, + /* X_ADD_ST_USQ */ IS_USEPR + IS_STORE + IS_SPREL + IS_SHORT, + /* X_ADD_ST_WATQ */ IS_USEPR + IS_STORE + IS_POPWT, + /* X_ADD_ST_UATQ */ IS_USEPR + IS_STORE + IS_POPWT + IS_SHORT, + /* X_ADD_ST_WAXQ */ IS_USEPR + IS_STORE, + /* X_ADD_ST_UAXQ */ IS_USEPR + IS_STORE + IS_SHORT, + + /* X_ADD_ST_WMIQ */ IS_USEPR + IS_STORE, + /* X_ADD_ST_UMIQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_ADD_ST_WPIQ */ IS_USEPR + IS_STORE, + /* X_ADD_ST_UPIQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_ADD_ST_WSIQ */ IS_USEPR + IS_STORE + IS_SPREL, + /* X_ADD_ST_USIQ */ IS_USEPR + IS_STORE + IS_SPREL + IS_SHORT, + /* X_ADD_ST_WATIQ */ IS_USEPR + IS_STORE + IS_POPWT, + /* X_ADD_ST_UATIQ */ IS_USEPR + IS_STORE + IS_POPWT + IS_SHORT, + /* X_ADD_ST_WAXIQ */ IS_USEPR + IS_STORE, + /* X_ADD_ST_UAXIQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* I_SUB_WT */ IS_USEPR + IS_POPWT, /* I_SUB_WI */ IS_USEPR, + /* X_SUB_WM */ IS_USEPR, /* X_SUB_UM */ IS_USEPR, /* X_SUB_WP */ IS_USEPR, @@ -428,8 +457,20 @@ unsigned char icode_flags[] = { /* X_SUB_WAX */ IS_USEPR, /* X_SUB_UAX */ IS_USEPR, + /* X_SUB_ST_WMIQ */ IS_USEPR + IS_STORE, + /* X_SUB_ST_UMIQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_SUB_ST_WPIQ */ IS_USEPR + IS_STORE, + /* X_SUB_ST_UPIQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_SUB_ST_WSIQ */ IS_USEPR + IS_STORE + IS_SPREL, + /* X_SUB_ST_USIQ */ IS_USEPR + IS_STORE + IS_SPREL + IS_SHORT, + /* X_SUB_ST_WATIQ */ IS_USEPR + IS_STORE + IS_POPWT, + /* X_SUB_ST_UATIQ */ IS_USEPR + IS_STORE + IS_POPWT + IS_SHORT, + /* X_SUB_ST_WAXIQ */ IS_USEPR + IS_STORE, + /* X_SUB_ST_UAXIQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_ISUB_WT */ IS_USEPR + IS_POPWT, /* X_ISUB_WI */ IS_USEPR, + /* X_ISUB_WM */ IS_USEPR, /* X_ISUB_UM */ IS_USEPR, /* X_ISUB_WP */ IS_USEPR, @@ -441,9 +482,21 @@ unsigned char icode_flags[] = { /* X_ISUB_WAX */ IS_USEPR, /* X_ISUB_UAX */ IS_USEPR, + /* X_ISUB_ST_WMQ */ IS_USEPR + IS_STORE, + /* X_ISUB_ST_UMQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_ISUB_ST_WPQ */ IS_USEPR + IS_STORE, + /* X_ISUB_ST_UPQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_ISUB_ST_WSQ */ IS_USEPR + IS_STORE + IS_SPREL, + /* X_ISUB_ST_USQ */ IS_USEPR + IS_STORE + IS_SPREL + IS_SHORT, + /* X_ISUB_ST_WATQ */ IS_USEPR + IS_STORE + IS_POPWT, + /* X_ISUB_ST_UATQ */ IS_USEPR + IS_STORE + IS_POPWT + IS_SHORT, + /* X_ISUB_ST_WAXQ */ IS_USEPR + IS_STORE, + /* X_ISUB_ST_UAXQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* I_AND_WT */ IS_USEPR + IS_POPWT, /* X_AND_WI */ IS_USEPR, /* X_AND_UIQ */ IS_USEPR + IS_UBYTE, + /* X_AND_WM */ IS_USEPR, /* X_AND_UM */ IS_USEPR, /* X_AND_WP */ IS_USEPR, @@ -455,8 +508,20 @@ unsigned char icode_flags[] = { /* X_AND_WAX */ IS_USEPR, /* X_AND_UAX */ IS_USEPR, + /* X_AND_ST_WMQ */ IS_USEPR + IS_STORE, + /* X_AND_ST_UMQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_AND_ST_WPQ */ IS_USEPR + IS_STORE, + /* X_AND_ST_UPQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_AND_ST_WSQ */ IS_USEPR + IS_STORE + IS_SPREL, + /* X_AND_ST_USQ */ IS_USEPR + IS_STORE + IS_SPREL + IS_SHORT, + /* X_AND_ST_WATQ */ IS_USEPR + IS_STORE + IS_POPWT, + /* X_AND_ST_UATQ */ IS_USEPR + IS_STORE + IS_POPWT + IS_SHORT, + /* X_AND_ST_WAXQ */ IS_USEPR + IS_STORE, + /* X_AND_ST_UAXQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* I_EOR_WT */ IS_USEPR + IS_POPWT, /* X_EOR_WI */ IS_USEPR, + /* X_EOR_WM */ IS_USEPR, /* X_EOR_UM */ IS_USEPR, /* X_EOR_WP */ IS_USEPR, @@ -468,8 +533,20 @@ unsigned char icode_flags[] = { /* X_EOR_WAX */ IS_USEPR, /* X_EOR_UAX */ IS_USEPR, + /* X_EOR_ST_WMQ */ IS_USEPR + IS_STORE, + /* X_EOR_ST_UMQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_EOR_ST_WPQ */ IS_USEPR + IS_STORE, + /* X_EOR_ST_UPQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_EOR_ST_WSQ */ IS_USEPR + IS_STORE + IS_SPREL, + /* X_EOR_ST_USQ */ IS_USEPR + IS_STORE + IS_SPREL + IS_SHORT, + /* X_EOR_ST_WATQ */ IS_USEPR + IS_STORE + IS_POPWT, + /* X_EOR_ST_UATQ */ IS_USEPR + IS_STORE + IS_POPWT + IS_SHORT, + /* X_EOR_ST_WAXQ */ IS_USEPR + IS_STORE, + /* X_EOR_ST_UAXQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* I_OR_WT */ IS_USEPR + IS_POPWT, /* X_OR_WI */ IS_USEPR, + /* X_OR_WM */ IS_USEPR, /* X_OR_UM */ IS_USEPR, /* X_OR_WP */ IS_USEPR, @@ -481,6 +558,17 @@ unsigned char icode_flags[] = { /* X_OR_WAX */ IS_USEPR, /* X_OR_UAX */ IS_USEPR, + /* X_OR_ST_WMQ */ IS_USEPR + IS_STORE, + /* X_OR_ST_UMQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_OR_ST_WPQ */ IS_USEPR + IS_STORE, + /* X_OR_ST_UPQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* X_OR_ST_WSQ */ IS_USEPR + IS_STORE + IS_SPREL, + /* X_OR_ST_USQ */ IS_USEPR + IS_STORE + IS_SPREL + IS_SHORT, + /* X_OR_ST_WATQ */ IS_USEPR + IS_STORE + IS_POPWT, + /* X_OR_ST_UATQ */ IS_USEPR + IS_STORE + IS_POPWT + IS_SHORT, + /* X_OR_ST_WAXQ */ IS_USEPR + IS_STORE, + /* X_OR_ST_UAXQ */ IS_USEPR + IS_STORE + IS_SHORT, + /* I_ASL_WR */ IS_USEPR, /* I_ASL_WT */ IS_USEPR + IS_POPWT, /* I_ASL_WI */ IS_USEPR, @@ -561,23 +649,23 @@ int q_nb; /* externs */ extern int arg_stack_flag; -int cmp_operands (INS *p1, INS *p2) +bool cmp_operands (INS *p1, INS *p2) { #ifdef DEBUG_OPTIMIZER printf("cmp"); dump_ins(p1); dump_ins(p2); #endif if (p1->ins_type != p2->ins_type) - return (0); + return (false); if (p1->ins_type == T_SYMBOL) { if (strcmp(((SYMBOL *)p1->ins_data)->name, ((SYMBOL *)p2->ins_data)->name) != 0) - return (0); + return (false); } else { if (p1->ins_data != p2->ins_data) - return (0); + return (false); } - return (1); + return (true); } inline bool is_sprel (INS *i) @@ -712,20 +800,32 @@ void push_ins (INS *ins) remove = 1; /* - * __ld.wi i --> __st.{w/u}miq symbol, i + * __ld.wi i --> __st.{w/u}miq i, symbol * __st.{w/u}m symbol * __fence * - * __ld.wi i --> __st.{w/u}siq n, 1 + * __ld.wi i --> __st.{w/u}siq i, n * __st.{w/u}s n * __fence + * + * __ld.wi i --> __st.{w/u}atiq i, array + * __st.{w/u}at array + * __fence + * + * __ld.wi i --> __st.{w/u}axiq i, array + * __st.{w/u}ax array + * __fence */ if ((p_nb >= 3) && (p[1]->ins_code == I_ST_WM || p[1]->ins_code == I_ST_UM || p[1]->ins_code == X_ST_WS || - p[1]->ins_code == X_ST_US) && + p[1]->ins_code == X_ST_US || + p[1]->ins_code == X_ST_WAT || + p[1]->ins_code == X_ST_UAT || + p[1]->ins_code == X_ST_WAX || + p[1]->ins_code == X_ST_UAX) && (p[2]->ins_code == I_LD_WI) && (p[2]->ins_type == T_VALUE) ) { @@ -737,7 +837,11 @@ void push_ins (INS *ins) case I_ST_UM: p[2]->ins_code = I_ST_UMIQ; break; case X_ST_WS: p[2]->ins_code = I_ST_WSIQ; break; case X_ST_US: p[2]->ins_code = I_ST_USIQ; break; - default: abort(); + case X_ST_WAT: p[2]->ins_code = X_ST_WATIQ; break; + case X_ST_UAT: p[2]->ins_code = X_ST_UATIQ; break; + case X_ST_WAX: p[2]->ins_code = X_ST_WAXIQ; break; + case X_ST_UAX: p[2]->ins_code = X_ST_UAXIQ; break; + default: break; } p[2]->imm_type = T_VALUE; p[2]->imm_data = data; @@ -756,6 +860,285 @@ void push_ins (INS *ins) remove = 2; } + /* + * __add.wm symbol --> __add_st.wmq symbol + * __st.wm symbol + * __fence + * + * __add.um symbol --> __add_st.umq symbol + * __st.um symbol + * __fence + * + * __isub.wm symbol --> __isub_st.wmq symbol + * __st.wm symbol + * __fence + * + * __isub.um symbol --> __isub_st.umq symbol + * __st.um symbol + * __fence + * + * etc, etc + * + * this optimizes the store for a "+=", "-=", "&=", "^=", "|=". + */ + else if + ((p_nb >= 3) && + (p[1]->ins_code == I_ST_WM || + p[1]->ins_code == I_ST_UM) && + (p[2]->ins_code == X_ADD_WM || + p[2]->ins_code == X_ADD_UM || + p[2]->ins_code == X_ISUB_WM || + p[2]->ins_code == X_ISUB_UM || + p[2]->ins_code == X_AND_WM || + p[2]->ins_code == X_AND_UM || + p[2]->ins_code == X_EOR_WM || + p[2]->ins_code == X_EOR_UM || + p[2]->ins_code == X_OR_WM || + p[2]->ins_code == X_OR_UM) && + (cmp_operands(p[1], p[2])) + ) { + /* replace code */ + remove = 2; + if (p[1]->ins_code == I_ST_WM) { + switch (p[2]->ins_code) { + case X_ADD_WM: p[2]->ins_code = X_ADD_ST_WMQ; break; + case X_ISUB_WM: p[2]->ins_code = X_ISUB_ST_WMQ; break; + case X_AND_WM: p[2]->ins_code = X_AND_ST_WMQ; break; + case X_EOR_WM: p[2]->ins_code = X_EOR_ST_WMQ; break; + case X_OR_WM: p[2]->ins_code = X_OR_ST_WMQ; break; + default: remove = 1; break; /* this should never happen! */ + } + } else { + switch (p[2]->ins_code) { + case X_ADD_UM: p[2]->ins_code = X_ADD_ST_UMQ; break; + case X_ISUB_UM: p[2]->ins_code = X_ISUB_ST_UMQ; break; + case X_AND_UM: p[2]->ins_code = X_AND_ST_UMQ; break; + case X_EOR_UM: p[2]->ins_code = X_EOR_ST_UMQ; break; + case X_OR_UM: p[2]->ins_code = X_OR_ST_UMQ; break; + default: remove = 1; break; /* this should never happen! */ + } + } + } + + /* + * __add.ws n --> __add_st.wsq n + * __st.ws n + * __fence + * + * __add.us n --> __add_st.usq n + * __st.us n + * __fence + * + * __isub.ws n --> __isub_st.wsq n + * __st.ws n + * __fence + * + * __isub.us n --> __isub_st.usq n + * __st.us n + * __fence + * + * etc, etc + * + * this optimizes the store for a "+=", "-=", "&=", "^=", "|=". + */ + else if + ((p_nb >= 3) && + (p[1]->ins_code == X_ST_WS || + p[1]->ins_code == X_ST_US) && + (p[2]->ins_code == X_ADD_WS || + p[2]->ins_code == X_ADD_US || + p[2]->ins_code == X_ISUB_WS || + p[2]->ins_code == X_ISUB_US || + p[2]->ins_code == X_AND_WS || + p[2]->ins_code == X_AND_US || + p[2]->ins_code == X_EOR_WS || + p[2]->ins_code == X_EOR_US || + p[2]->ins_code == X_OR_WS || + p[2]->ins_code == X_OR_US) && + (cmp_operands(p[1], p[2])) + ) { + /* replace code */ + remove = 2; + if (p[1]->ins_code == X_ST_WS) { + switch (p[2]->ins_code) { + case X_ADD_WS: p[2]->ins_code = X_ADD_ST_WSQ; break; + case X_ISUB_WS: p[2]->ins_code = X_ISUB_ST_WSQ; break; + case X_AND_WS: p[2]->ins_code = X_AND_ST_WSQ; break; + case X_EOR_WS: p[2]->ins_code = X_EOR_ST_WSQ; break; + case X_OR_WS: p[2]->ins_code = X_OR_ST_WSQ; break; + default: remove = 1; break; /* this should never happen! */ + } + } else { + switch (p[2]->ins_code) { + case X_ADD_US: p[2]->ins_code = X_ADD_ST_USQ; break; + case X_ISUB_US: p[2]->ins_code = X_ISUB_ST_USQ; break; + case X_AND_US: p[2]->ins_code = X_AND_ST_USQ; break; + case X_EOR_US: p[2]->ins_code = X_EOR_ST_USQ; break; + case X_OR_US: p[2]->ins_code = X_OR_ST_USQ; break; + default: remove = 1; break; /* this should never happen! */ + } + } + } + + /* + * __add.wat array --> __add_st.watq array + * __st.wax array + * __fence + * + * __add.uat array --> __add_st.uatq array + * __st.uax array + * __fence + * + * __isub.wat array --> __isub_st.watq array + * __st.wax array + * __fence + * + * __isub.uat array --> __isub_st.uatq array + * __st.uax array + * __fence + * + * etc, etc + * + * this optimizes the store for a "+=", "-=", "&=", "^=", "|=". + */ + else if + ((p_nb >= 3) && + (p[1]->ins_code == X_ST_WAX || + p[1]->ins_code == X_ST_UAX) && + (p[2]->ins_code == X_ADD_WAT || + p[2]->ins_code == X_ADD_UAT || + p[2]->ins_code == X_ISUB_WAT || + p[2]->ins_code == X_ISUB_UAT || + p[2]->ins_code == X_AND_WAT || + p[2]->ins_code == X_AND_UAT || + p[2]->ins_code == X_EOR_WAT || + p[2]->ins_code == X_EOR_UAT || + p[2]->ins_code == X_OR_WAT || + p[2]->ins_code == X_OR_UAT) && + (cmp_operands(p[1], p[2])) + ) { + /* replace code */ + remove = 2; + if (p[1]->ins_code == X_ST_WAX) { + switch (p[2]->ins_code) { + case X_ADD_WAT: p[2]->ins_code = X_ADD_ST_WATQ; break; + case X_ISUB_WAT: p[2]->ins_code = X_ISUB_ST_WATQ; break; + case X_AND_WAT: p[2]->ins_code = X_AND_ST_WATQ; break; + case X_EOR_WAT: p[2]->ins_code = X_EOR_ST_WATQ; break; + case X_OR_WAT: p[2]->ins_code = X_OR_ST_WATQ; break; + default: remove = 1; break; /* this should never happen! */ + } + } else { + switch (p[2]->ins_code) { + case X_ADD_UAT: p[2]->ins_code = X_ADD_ST_UATQ; break; + case X_ISUB_UAT: p[2]->ins_code = X_ISUB_ST_UATQ; break; + case X_AND_UAT: p[2]->ins_code = X_AND_ST_UATQ; break; + case X_EOR_UAT: p[2]->ins_code = X_EOR_ST_UATQ; break; + case X_OR_UAT: p[2]->ins_code = X_OR_ST_UATQ; break; + default: remove = 1; break; /* this should never happen! */ + } + } + } + + /* + * __add.wax array --> __add_st.waxq array + * __st.wax array + * __fence + * + * __add.uax array --> __add_st.uaxq array + * __st.uax array + * __fence + * + * __isub.wax array --> __isub_st.waxq array + * __st.wax array + * __fence + * + * __isub.uax array --> __isub_st.uaxq array + * __st.uax array + * __fence + * + * etc, etc + * + * this optimizes the store for a "+=", "-=", "&=", "^=", "|=". + */ + else if + ((p_nb >= 3) && + (p[1]->ins_code == X_ST_WAX || + p[1]->ins_code == X_ST_UAX) && + (p[2]->ins_code == X_ADD_WAX || + p[2]->ins_code == X_ADD_UAX || + p[2]->ins_code == X_ISUB_WAX || + p[2]->ins_code == X_ISUB_UAX || + p[2]->ins_code == X_AND_WAX || + p[2]->ins_code == X_AND_UAX || + p[2]->ins_code == X_EOR_WAX || + p[2]->ins_code == X_EOR_UAX || + p[2]->ins_code == X_OR_WAX || + p[2]->ins_code == X_OR_UAX) && + (cmp_operands(p[1], p[2])) + ) { + /* replace code */ + remove = 2; + if (p[1]->ins_code == X_ST_WAX) { + switch (p[2]->ins_code) { + case X_ADD_WAX: p[2]->ins_code = X_ADD_ST_WAXQ; break; + case X_ISUB_WAX: p[2]->ins_code = X_ISUB_ST_WAXQ; break; + case X_AND_WAX: p[2]->ins_code = X_AND_ST_WAXQ; break; + case X_EOR_WAX: p[2]->ins_code = X_EOR_ST_WAXQ; break; + case X_OR_WAX: p[2]->ins_code = X_OR_ST_WAXQ; break; + default: remove = 1; break; /* this should never happen! */ + } + } else { + switch (p[2]->ins_code) { + case X_ADD_UAX: p[2]->ins_code = X_ADD_ST_UAXQ; break; + case X_ISUB_UAX: p[2]->ins_code = X_ISUB_ST_UAXQ; break; + case X_AND_UAX: p[2]->ins_code = X_AND_ST_UAXQ; break; + case X_EOR_UAX: p[2]->ins_code = X_EOR_ST_UAXQ; break; + case X_OR_UAX: p[2]->ins_code = X_OR_ST_UAXQ; break; + default: remove = 1; break; /* this should never happen! */ + } + } + } + + /* + * __st.{w/u}m symbol --> __st.{w/u}mq symbol + * __fence + * + * __st.{w/u}p symbol --> __st.{w/u}pq symbol + * __fence + * + * __st.{w/u}s n --> __st.{w/u}sq n + * __fence + * + * __st.{w/u}at array --> __st.{w/u}atq array + * __fence + * + * __st.{w/u}ax array --> __st.{w/u}axq array + * __fence + */ + else if + ((p_nb >= 2) && + (icode_flags[p[1]->ins_code] & IS_STORE) + ) { + /* replace code */ + switch (p[1]->ins_code) { + case I_ST_WPT: p[1]->ins_code = X_ST_WPTQ; break; + case I_ST_UPT: p[1]->ins_code = X_ST_UPTQ; break; + case I_ST_WM: p[1]->ins_code = X_ST_WMQ; break; + case I_ST_UM: p[1]->ins_code = X_ST_UMQ; break; + case X_ST_WP: p[1]->ins_code = X_ST_WPQ; break; + case X_ST_UP: p[1]->ins_code = X_ST_UPQ; break; + case X_ST_WS: p[1]->ins_code = X_ST_WSQ; break; + case X_ST_US: p[1]->ins_code = X_ST_USQ; break; + case X_ST_WAT: p[1]->ins_code = X_ST_WATQ; break; + case X_ST_UAT: p[1]->ins_code = X_ST_UATQ; break; + case X_ST_WAX: p[1]->ins_code = X_ST_WAXQ; break; + case X_ST_UAX: p[1]->ins_code = X_ST_UAXQ; break; + default: break; + } + remove = 1; + } + /* * __ldinc.wm / __incld.wm --> __inc.wm * __fence @@ -2799,7 +3182,7 @@ void push_ins (INS *ins) p[2]->ins_code == I_LD_UM) && (p[0]->ins_type == p[2]->ins_type) && (p[0]->ins_data == p[2]->ins_data) -// (cmp_operands(p[0], p[2]) == 1) +// (cmp_operands(p[0], p[2])) ) { /* replace code */ switch (p[2]->ins_code) { @@ -2890,7 +3273,7 @@ void push_ins (INS *ins) p[2]->ins_code == X_LDP_UAY) && (p[0]->ins_type == p[2]->ins_type) && (p[0]->ins_data == p[2]->ins_data) -// (cmp_operands(p[0], p[2]) == 1) +// (cmp_operands(p[0], p[2])) ) { /* replace code */ switch (p[2]->ins_code) { @@ -3206,7 +3589,7 @@ void push_ins (INS *ins) else if ((p[0]->ins_code == I_LD_WM) && (p[1]->ins_code == I_ST_WM) && - (cmp_operands(p[0], p[1]) == 1) + (cmp_operands(p[0], p[1])) ) { /* remove code */ remove = 1; @@ -3715,6 +4098,159 @@ void push_ins (INS *ins) goto lv1_loop; } + /* + * __ld.wi i --> __ldx.{w/b/u}mq index + * __ldx.{w/b/u}mq index __ld.wi i + * + * __ld.wi i --> __ldx.{w/b/u}sq index + * __ldx.{w/b/u}s index __ld.wi i + * + * __ld.wi i --> __ld2x.{w/b/u}mq index + * __ld2x.{w/b/u}m index __ld.wi i + * + * __ld.wi i --> __ld2x.{w/b/u}sq index + * __ld2x.{w/b/u}s index __ld.wi i + * + * __ld.{w/b/u}m symbol --> __ldx.{w/b/u}mq index + * __ldx.{w/b/u}mq index __ld.{w/b/u}m symbol + * + * __ld.{w/b/u}m symbol --> __ldx.{w/b/u}sq index + * __ldx.{w/b/u}s index __ld.{w/b/u}m symbol + * + * __ld.{w/b/u}m symbol --> __ld2x.{w/b/u}mq index + * __ld2x.{w/b/u}m index __ld.{w/b/u}m symbol + * + * __ld.{w/b/u}m symbol --> __ld2x.{w/b/u}sq index + * __ld2x.{w/b/u}s index __ld.{w/b/u}m symbol + * + * swap the LDX so that it doesn't have to preserve the primary register + */ + else if + ((p[0]->ins_code == X_LDX_WMQ || + p[0]->ins_code == X_LDX_BMQ || + p[0]->ins_code == X_LDX_UMQ || + p[0]->ins_code == X_LDX_WS || + p[0]->ins_code == X_LDX_BS || + p[0]->ins_code == X_LDX_US || + p[0]->ins_code == X_LD2X_WM || + p[0]->ins_code == X_LD2X_BM || + p[0]->ins_code == X_LD2X_UM || + p[0]->ins_code == X_LD2X_WS || + p[0]->ins_code == X_LD2X_BS || + p[0]->ins_code == X_LD2X_US) && + (p[1]->ins_code == I_LD_WI || + p[1]->ins_code == I_LD_WM || + p[1]->ins_code == I_LD_BM || + p[1]->ins_code == I_LD_UM) + ) { + /* replace code */ + INS parked = *p[1]; + *p[1] = *p[0]; + *p[0] = parked; + switch (p[1]->ins_code) { + case X_LDX_WMQ: p[1]->ins_code = X_LDX_WMQ; break; + case X_LDX_BMQ: p[1]->ins_code = X_LDX_BMQ; break; + case X_LDX_UMQ: p[1]->ins_code = X_LDX_UMQ; break; + case X_LDX_WS : p[1]->ins_code = X_LDX_WSQ; break; + case X_LDX_BS : p[1]->ins_code = X_LDX_BSQ; break; + case X_LDX_US : p[1]->ins_code = X_LDX_USQ; break; + case X_LD2X_WM: p[1]->ins_code = X_LD2X_WMQ; break; + case X_LD2X_BM: p[1]->ins_code = X_LD2X_BMQ; break; + case X_LD2X_UM: p[1]->ins_code = X_LD2X_UMQ; break; + case X_LD2X_WS: p[1]->ins_code = X_LD2X_WSQ; break; + case X_LD2X_BS: p[1]->ins_code = X_LD2X_BSQ; break; + case X_LD2X_US: p[1]->ins_code = X_LD2X_USQ; break; + default: break; + } + /* no instructions removed, just loop */ + goto lv1_loop; + } + + /* + * __ld.wi i --> __add_st.{w/u}miq i, symbol + * __add_st.{w/u}mq symbol + * + * __ld.wi i --> __sub_st.{w/u}miq i, symbol + * __isub_st.{w/u}mq symbol + * + * __ld.wi i --> __add_st.{w/u}piq i, symbol + * __add_st.{w/u}pq symbol + * + * __ld.wi i --> __sub_st.{w/u}piq i, symbol + * __isub_st.{w/u}pq symbol + * + * __ld.wi i --> __add_st.{w/u}siq i, n + * __add_st.{w/u}sq n + * + * __ld.wi i --> __sub_st.{w/u}siq i, n + * __isub_st.{w/u}sq n + * + * __ld.wi i --> __add_st.{w/u}atiq i, symbol + * __add_st.{w/u}atq symbol + * + * __ld.wi i --> __sub_st.{w/u}atiq i, symbol + * __isub_st.{w/u}atq symbol + * + * __ld.wi i --> __add_st.{w/u}axiq i, symbol + * __add_st.{w/u}axq symbol + * + * __ld.wi i --> __sub_st.{w/u}axiq i, symbol + * __isub_st.{w/u}axq symbol + */ + else if + ((p[1]->ins_code == I_LD_WI) && + (p[0]->ins_code == X_ADD_ST_WMQ || + p[0]->ins_code == X_ADD_ST_UMQ || + p[0]->ins_code == X_ADD_ST_WPQ || + p[0]->ins_code == X_ADD_ST_UPQ || + p[0]->ins_code == X_ADD_ST_WSQ || + p[0]->ins_code == X_ADD_ST_USQ || + p[0]->ins_code == X_ADD_ST_WATQ || + p[0]->ins_code == X_ADD_ST_UATQ || + p[0]->ins_code == X_ADD_ST_WAXQ || + p[0]->ins_code == X_ADD_ST_UAXQ || + p[0]->ins_code == X_ISUB_ST_WMQ || + p[0]->ins_code == X_ISUB_ST_UMQ || + p[0]->ins_code == X_ISUB_ST_WPQ || + p[0]->ins_code == X_ISUB_ST_UPQ || + p[0]->ins_code == X_ISUB_ST_WSQ || + p[0]->ins_code == X_ISUB_ST_USQ || + p[0]->ins_code == X_ISUB_ST_WATQ || + p[0]->ins_code == X_ISUB_ST_UATQ || + p[0]->ins_code == X_ISUB_ST_WAXQ || + p[0]->ins_code == X_ISUB_ST_UAXQ) + ) { + /* replace code */ + intptr_t data = p[1]->ins_data; + *p[1] = *p[0]; + switch (p[1]->ins_code) { + case X_ADD_ST_WMQ: p[1]->ins_code = X_ADD_ST_WMIQ; break; + case X_ADD_ST_UMQ: p[1]->ins_code = X_ADD_ST_UMIQ; break; + case X_ADD_ST_WPQ: p[1]->ins_code = X_ADD_ST_WPIQ; break; + case X_ADD_ST_UPQ: p[1]->ins_code = X_ADD_ST_UPIQ; break; + case X_ADD_ST_WSQ: p[1]->ins_code = X_ADD_ST_WSIQ; break; + case X_ADD_ST_USQ: p[1]->ins_code = X_ADD_ST_USIQ; break; + case X_ADD_ST_WATQ: p[1]->ins_code = X_ADD_ST_WATIQ; break; + case X_ADD_ST_UATQ: p[1]->ins_code = X_ADD_ST_UATIQ; break; + case X_ADD_ST_WAXQ: p[1]->ins_code = X_ADD_ST_WAXIQ; break; + case X_ADD_ST_UAXQ: p[1]->ins_code = X_ADD_ST_UAXQ; break; + case X_ISUB_ST_WMQ: p[1]->ins_code = X_SUB_ST_WMIQ; break; + case X_ISUB_ST_UMQ: p[1]->ins_code = X_SUB_ST_UMIQ; break; + case X_ISUB_ST_WPQ: p[1]->ins_code = X_SUB_ST_WPIQ; break; + case X_ISUB_ST_UPQ: p[1]->ins_code = X_SUB_ST_UPIQ; break; + case X_ISUB_ST_WSQ: p[1]->ins_code = X_SUB_ST_WSIQ; break; + case X_ISUB_ST_USQ: p[1]->ins_code = X_SUB_ST_USIQ; break; + case X_ISUB_ST_WATQ: p[1]->ins_code = X_SUB_ST_WATIQ; break; + case X_ISUB_ST_UATQ: p[1]->ins_code = X_SUB_ST_UATIQ; break; + case X_ISUB_ST_WAXQ: p[1]->ins_code = X_SUB_ST_WAXIQ; break; + case X_ISUB_ST_UAXQ: p[1]->ins_code = X_SUB_ST_UAXIQ; break; + default: break; + } + p[1]->imm_type = T_VALUE; + p[1]->imm_data = data; + remove = 1; + } + /* remove instructions from queue and begin again */ if (remove) goto lv1_loop;