diff --git a/include/hucc/hucc-codegen.asm b/include/hucc/hucc-codegen.asm index 4a0168ec..1feef283 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 ; ************** @@ -4225,7 +4237,7 @@ __st.wpiq .macro __st.upiq .macro sta.l __ptr sty.h __ptr - lda #\1 + lda.l #\1 sta [__ptr] .endm @@ -4287,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 @@ -4326,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) @@ -5369,6 +5453,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 @@ -5607,62 +5720,171 @@ __mul.wi .macro .endm ; ************** -; Y:A = stacked-value / Y:A - -__sdiv.wt .macro - sta.l = 17) + ldy #\1 + jsr __muluchar + .endif + .endm + +; ************** +; Y:A = stacked-value / Y:A + +__sdiv.wt .macro + sta.l = 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 + ; *************************************************************************** @@ -6175,6 +6882,7 @@ __ldd_s_b .macro ; __STACK .endm + .list ; *************************************************************************** ; *************************************************************************** diff --git a/src/hucc/code.c b/src/hucc/code.c index 0535126c..0f000aec 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); @@ -1942,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); @@ -1966,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: @@ -2058,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; @@ -2130,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; @@ -2202,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; @@ -2280,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; @@ -2352,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; @@ -2424,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; @@ -2434,6 +2961,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; @@ -2474,6 +3007,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 3b097094..1029bb2a 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, @@ -350,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 */ @@ -367,6 +376,7 @@ enum ICODE { I_ADD_WT, I_ADD_WI, + X_ADD_WM, X_ADD_UM, X_ADD_WP, @@ -378,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, @@ -391,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, @@ -404,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, @@ -418,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, @@ -431,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, @@ -444,9 +525,21 @@ 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, - I_ASL_WR, + I_ASL_UIQ, I_ASR_WT, I_ASR_WI, @@ -457,6 +550,7 @@ enum ICODE { I_MUL_WT, I_MUL_WI, + I_MUL_UIQ, I_SDIV_WT, I_SDIV_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 3b9a14f9..78e61952 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, @@ -379,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 @@ -400,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, @@ -411,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, @@ -424,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, @@ -437,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, @@ -451,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, @@ -464,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, @@ -477,9 +558,21 @@ 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, - /* I_ASL_WR */ IS_USEPR, + /* I_ASL_UIQ */ IS_USEPR, /* I_ASR_WT */ IS_USEPR + IS_POPWT, /* I_ASR_WI */ IS_USEPR, @@ -490,6 +583,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, @@ -555,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) @@ -706,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) ) { @@ -731,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; @@ -750,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 @@ -1546,7 +1935,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 +1975,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 +2950,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; @@ -2775,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) { @@ -2866,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) { @@ -3182,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; @@ -3483,6 +3890,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 @@ -3641,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; @@ -4254,9 +4864,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 +4989,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)