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;