Hi Guys, I am applying the patch below to the MSP430 backend to enable the use of %A, %B, %C and %D in asm statements as selectors of 16-bit parts of a 64-bit value. This is at the request of TI, for compatibility with their compiler.
Cheers Nick gcc/ChangeLog 2013-12-30 Nick Clifton <ni...@redhat.com> * config/msp430/msp430.c (msp430_print_operand): Rename %B to %b and %A to %Q. Add %A, %B, %C and %D as selectors for 16-bit parts of a 64-bit operand. * config/msp430/msp430.md: Replace uses of %B with %b and uses of %A with %q. Index: gcc/config/msp430/msp430.c =================================================================== --- gcc/config/msp430/msp430.c (revision 206246) +++ gcc/config/msp430/msp430.c (working copy) @@ -1914,6 +1914,24 @@ #undef TARGET_PRINT_OPERAND #define TARGET_PRINT_OPERAND msp430_print_operand +/* A low 16-bits of int/lower of register pair + B high 16-bits of int/higher of register pair + C bits 32-47 of a 64-bit value/reg 3 of a DImode value + D bits 48-63 of a 64-bit value/reg 4 of a DImode value + H like %B (for backwards compatibility) + I inverse of value + L like %A (for backwards compatibility) + O offset of the top of the stack + Q like X but generates an A postfix + R inverse of condition code, unsigned. + X X instruction postfix in large mode + Y value - 4 + Z value - 1 + b .B or .W or .A, depending upon the mode + p bit position + r inverse of condition code + x like X but only for pointers. */ + static void msp430_print_operand (FILE * file, rtx op, int letter) { @@ -1978,7 +1996,7 @@ gcc_assert (CONST_INT_P (op)); fprintf (file, "#%d", 1 << INTVAL (op)); return; - case 'B': + case 'b': switch (GET_MODE (op)) { case QImode: fprintf (file, ".B"); return; @@ -1988,6 +2006,7 @@ default: return; } + case 'A': case 'L': /* Low half. */ switch (GET_CODE (op)) { @@ -2005,6 +2024,7 @@ gcc_unreachable (); } break; + case 'B': case 'H': /* high half */ switch (GET_CODE (op)) { @@ -2023,6 +2043,42 @@ gcc_unreachable (); } break; + case 'C': + switch (GET_CODE (op)) + { + case MEM: + op = adjust_address (op, Pmode, 3); + break; + case REG: + op = gen_rtx_REG (Pmode, REGNO (op) + 2); + break; + case CONST_INT: + op = GEN_INT (INTVAL (op) >> 32); + letter = 0; + break; + default: + /* If you get here, figure out a test case :-) */ + gcc_unreachable (); + } + break; + case 'D': + switch (GET_CODE (op)) + { + case MEM: + op = adjust_address (op, Pmode, 4); + break; + case REG: + op = gen_rtx_REG (Pmode, REGNO (op) + 3); + break; + case CONST_INT: + op = GEN_INT (INTVAL (op) >> 48); + letter = 0; + break; + default: + /* If you get here, figure out a test case :-) */ + gcc_unreachable (); + } + break; case 'X': /* This is used to turn, for example, an ADD opcode into an ADDX @@ -2039,7 +2095,7 @@ fprintf (file, "X"); return; - case 'A': + case 'Q': /* Likewise, for BR -> BRA. */ if (TARGET_LARGE) fprintf (file, "A"); @@ -2053,6 +2109,12 @@ msp430_initial_elimination_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM) - 2); return; + + case 0: + break; + default: + output_operand_lossage ("invalid operand prefix"); + return; } switch (GET_CODE (op)) Index: gcc/config/msp430/msp430.md =================================================================== --- gcc/config/msp430/msp430.md (revision 206246) +++ gcc/config/msp430/msp430.md (working copy) @@ -87,7 +87,7 @@ [(unspec_volatile [(match_operand 0 "register_operand" "r") (match_operand 1 "immediate_operand" "n")] UNS_PUSHM)] "" - "PUSHM%B0\t%1, %0" + "PUSHM%b0\t%1, %0" ) (define_insn "pop" @@ -105,7 +105,7 @@ ) ;; This is nasty. Operand0 is bogus. It is only there so that we can get a -;; mode for the %B0 to work. We should use operand1 for this, but that does +;; mode for the %b0 to work. We should use operand1 for this, but that does ;; not have a mode. ;; ;; Operand1 is actually a register, but we cannot accept (REG...) because the @@ -115,7 +115,7 @@ ;; because that is the only operator that will omit the # prefix to an ;; integer value. Unfortunately it also inverts the integer value, so we ;; have pre-invert it when generating this insn. (We could of course add a -;; new operator, eg %D, just for this pattern...) +;; new operator, eg %J, just for this pattern...) ;; ;; The pushm pattern does not have this problem because of all of the ;; frame info cruft attached to it, so cprop_hardreg leaves it alone. @@ -124,7 +124,7 @@ (match_operand 1 "immediate_operand" "i") (match_operand 2 "immediate_operand" "i")] UNS_POPM)] "" - "POPM%B0\t%2, r%I1" + "POPM%b0\t%2, r%I1" ) ;; The next two patterns are here to support a "feature" of how GCC implements @@ -215,9 +215,9 @@ (match_operand:PSI 1 "msp_general_operand" "riYa,r,rmi"))] "" "@ - MOV%A0\t%1, %0 - MOV%A0\t%1, %0 - MOV%X0.%A0\t%1, %0") + MOV%Q0\t%1, %0 + MOV%Q0\t%1, %0 + MOV%X0.%Q0\t%1, %0") ; This pattern is identical to the truncsipsi2 pattern except ; that it uses a SUBREG instead of a TRUNC. It is needed in @@ -452,8 +452,8 @@ (match_operand 2 "msp430_inv_constgen_operator" "n,n")))] "" "@ - BIC%x0%B0\t#%I2, %0 - BIC%X0%B0\t#%I2, %0" + BIC%x0%b0\t#%I2, %0 + BIC%X0%b0\t#%I2, %0" ) (define_insn "bic<mode>3" @@ -462,8 +462,8 @@ (match_operand:QHI 2 "msp_nonimmediate_operand" "0,0")))] "" "@ - BIC%x0%B0\t%1, %0 - BIC%X0%B0\t%1, %0" + BIC%x0%b0\t%1, %0 + BIC%X0%b0\t%1, %0" ) (define_insn "and<mode>3" @@ -472,42 +472,42 @@ (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))] "" "@ - AND%x0%B0\t%2, %0 - AND%X0%B0\t%2, %0" + AND%x0%b0\t%2, %0 + AND%X0%b0\t%2, %0" ) (define_insn "ior<mode>3" - [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm") + [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm") (ior:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0") (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))] "" "@ - BIS%x0%B0\t%2, %0 - BIS%X0%B0\t%2, %0" + BIS%x0%b0\t%2, %0 + BIS%X0%b0\t%2, %0" ) (define_insn "xor<mode>3" - [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm") + [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm") (xor:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0") (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))] "" "@ - XOR%x0%B0\t%2, %0 - XOR%X0%B0\t%2, %0" + XOR%x0%b0\t%2, %0 + XOR%X0%b0\t%2, %0" ) ;; Macro : XOR #~0, %0 (define_insn "one_cmpl<mode>2" - [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m") + [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m") (not:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "0,0")))] "" "@ - INV%x0%B0\t%0 - INV%X0%B0\t%0" + INV%x0%b0\t%0 + INV%X0%b0\t%0" ) (define_insn "extendqihi2" - [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,m") + [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,m") (sign_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))] "" "@ @@ -920,7 +920,7 @@ (define_insn "epilogue_helper" [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)] "" - "BR%A0\t#__mspabi_func_epilog_%D0" + "BR%Q0\t#__mspabi_func_epilog_%0" ) @@ -956,7 +956,7 @@ [(call (mem:HI (match_operand 0 "general_operand" "rmi")) (match_operand 1 ""))] "" - "CALL%A0\t%0" + "CALL%Q0\t%0" ) (define_expand "call_value" @@ -972,7 +972,7 @@ (call (mem:HI (match_operand 1 "general_operand" "rmi")) (match_operand 2 "")))] "" - "CALL%A0\t%1" + "CALL%Q0\t%1" ) (define_insn "msp_return" @@ -1010,7 +1010,7 @@ [(set (pc) (label_ref (match_operand 0 "" "")))] "" - "BR%A0\t#%l0" + "BR%Q0\t#%l0" ) ;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs @@ -1019,7 +1019,7 @@ [(set (pc) (match_operand 0 "nonimmediate_operand" "rYl"))] "" - "BR%A0\t%0" + "BR%Q0\t%0" ) ;;------------------------------------------------------------ @@ -1049,7 +1049,7 @@ ] "" "@ - CMP%A0\t%2, %1 { J%0\t%l3 + CMP%Q0\t%2, %1 { J%0\t%l3 CMPX.A\t%2, %1 { J%0\t%l3 CMPX.A\t%2, %1 { J%0\t%l3" ) @@ -1095,7 +1095,7 @@ ] "" "@ - CMP%A0\t%1, %2 { J%R0\t%l3 + CMP%Q0\t%1, %2 { J%R0\t%l3 CMPX.A\t%1, %2 { J%R0\t%l3 CMPX.A\t%1, %2 { J%R0\t%l3" ) @@ -1141,8 +1141,8 @@ ] "" "@ - BIT%x0%B0\t%1, %0 { JNE\t%l2 - BIT%X0%B0\t%1, %0 { JNE\t%l2" + BIT%x0%b0\t%1, %0 { JNE\t%l2 + BIT%X0%b0\t%1, %0 { JNE\t%l2" ) (define_insn "*bitbranch<mode>4" @@ -1155,7 +1155,7 @@ (clobber (reg:BI CARRY)) ] "" - "BIT%x0%X0%B0\t%1, %0 { JEQ\t%l2" + "BIT%x0%X0%b0\t%1, %0 { JEQ\t%l2" ) (define_insn "*bitbranch<mode>4" @@ -1168,7 +1168,7 @@ (clobber (reg:BI CARRY)) ] "" - "BIT%X0%B0\t%1, %0 { JNE\t%l2" + "BIT%X0%b0\t%1, %0 { JNE\t%l2" ) (define_insn "*bitbranch<mode>4" @@ -1181,7 +1181,7 @@ (clobber (reg:BI CARRY)) ] "" - "BIT%X0%B0\t%1, %0 { JEQ\t%l2" + "BIT%X0%b0\t%1, %0 { JEQ\t%l2" ) ;;------------------------------------------------------------ @@ -1199,8 +1199,8 @@ ] "" "@ - BIT%x0%B0\t%p1, %0 { JNE\t%l2 - BIT%X0%B0\t%p1, %0 { JNE\t%l2" + BIT%x0%b0\t%p1, %0 { JNE\t%l2 + BIT%X0%b0\t%p1, %0 { JNE\t%l2" ) (define_insn "*bitbranch<mode>4_z" @@ -1214,7 +1214,7 @@ (clobber (reg:BI CARRY)) ] "" - "BIT%x0%X0%B0\t%p1, %0 { JEQ\t%l2" + "BIT%x0%X0%b0\t%p1, %0 { JEQ\t%l2" ) (define_insn "*bitbranch<mode>4_z" @@ -1228,7 +1228,7 @@ (clobber (reg:BI CARRY)) ] "" - "BIT%X0%B0\t%p1, %0 { JNE\t%l2" + "BIT%X0%b0\t%p1, %0 { JNE\t%l2" ) (define_insn "*bitbranch<mode>4_z" @@ -1242,7 +1242,7 @@ (clobber (reg:BI CARRY)) ] "" - "BIT%X0%B0\t%p1, %0 { JEQ\t%l2" + "BIT%X0%b0\t%p1, %0 { JEQ\t%l2" ) ;;------------------------------------------------------------