diff options
Diffstat (limited to 'gas/config/xtensa-relax.c')
-rw-r--r-- | gas/config/xtensa-relax.c | 77 |
1 files changed, 55 insertions, 22 deletions
diff --git a/gas/config/xtensa-relax.c b/gas/config/xtensa-relax.c index cb296ed..daf15d5 100644 --- a/gas/config/xtensa-relax.c +++ b/gas/config/xtensa-relax.c @@ -87,13 +87,7 @@ when the first and second operands are not the same as specified by the "| %at!=%as" precondition clause. {"l32i %at,%as,%imm | %at!=%as", - "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"} - - There is special case for loop instructions here, but because we do - not currently have the ability to represent the difference of two - symbols, the conversion requires special code in the assembler to - write the operands of the addi/addmi pair representing the - difference of the old and new loop end label. */ + "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"} */ #include "as.h" #include "xtensa-isa.h" @@ -306,44 +300,83 @@ static string_pattern_pair widen_spec_list[] = {"l32i %at,%as,%imm | %at!=%as ? IsaUseConst16", "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l32i %at,%at,0"}, - /* This is only PART of the loop instruction. In addition, - hardcoded into its use is a modification of the final operand in - the instruction in bytes 9 and 12. */ - {"loop %as,%label | %as!=1 ? IsaUseLoops", + /* Widening loops with literals. */ + {"loop %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R", + "loop %as,%LABEL;" + "rsr.lend %as;" /* LEND */ + "wsr.lbeg %as;" /* LBEG */ + "LITERAL %label;" + "l32r %as, %LITERAL;" + "nop;" + "wsr.lend %as;" + "isync;" + "rsr.lcount %as;" /* LCOUNT */ + "addi %as, %as, 1;" + "LABEL"}, + {"loopgtz %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R", + "beqz %as,%label;" + "bltz %as,%label;" + "loopgtz %as,%LABEL;" + "rsr.lend %as;" /* LEND */ + "wsr.lbeg %as;" /* LBEG */ + "LITERAL %label;" + "l32r %as, %LITERAL;" + "nop;" + "wsr.lend %as;" + "isync;" + "rsr.lcount %as;" /* LCOUNT */ + "addi %as, %as, 1;" + "LABEL"}, + {"loopnez %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R", + "beqz %as,%label;" + "loopnez %as,%LABEL;" + "rsr.lend %as;" /* LEND */ + "wsr.lbeg %as;" /* LBEG */ + "LITERAL %label;" + "l32r %as, %LITERAL;" + "nop;" + "wsr.lend %as;" + "isync;" + "rsr.lcount %as;" /* LCOUNT */ + "addi %as, %as, 1;" + "LABEL"}, + + /* Widening loops with const16. */ + {"loop %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16", "loop %as,%LABEL;" "rsr.lend %as;" /* LEND */ "wsr.lbeg %as;" /* LBEG */ - "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */ - "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */ + "const16 %as,HI16U(%label);" + "const16 %as,LOW16U(%label);" "wsr.lend %as;" "isync;" "rsr.lcount %as;" /* LCOUNT */ - "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */ + "addi %as, %as, 1;" "LABEL"}, - {"loopgtz %as,%label | %as!=1 ? IsaUseLoops", + {"loopgtz %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16", "beqz %as,%label;" "bltz %as,%label;" "loopgtz %as,%LABEL;" "rsr.lend %as;" /* LEND */ "wsr.lbeg %as;" /* LBEG */ - "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */ - "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */ + "const16 %as,HI16U(%label);" + "const16 %as,LOW16U(%label);" "wsr.lend %as;" "isync;" "rsr.lcount %as;" /* LCOUNT */ - "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */ + "addi %as, %as, 1;" "LABEL"}, - {"loopnez %as,%label | %as!=1 ? IsaUseLoops", + {"loopnez %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16", "beqz %as,%label;" "loopnez %as,%LABEL;" "rsr.lend %as;" /* LEND */ "wsr.lbeg %as;" /* LBEG */ - "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */ - "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */ + "const16 %as,HI16U(%label);" + "const16 %as,LOW16U(%label);" "wsr.lend %as;" "isync;" "rsr.lcount %as;" /* LCOUNT */ - "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */ + "addi %as, %as, 1;" "LABEL"}, /* Relaxing to wide branches. Order is important here. With wide |