diff options
author | Jim Grosbach <grosbach@apple.com> | 2011-10-12 20:54:17 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2011-10-12 20:54:17 +0000 |
commit | c66e7afcf2810a2c1ebf08514eaf45c478e5ff67 (patch) | |
tree | b9461f30082990a38ecf151df0d807f0108b58fa | |
parent | 18ad76bb9aa1970958c52887eb4a648d1bac0a0e (diff) |
Thumb2 assembly parsing and encoding for LDC/STC.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141811 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 135 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 6 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 74 | ||||
-rw-r--r-- | test/MC/ARM/basic-thumb2-instructions.s | 120 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/thumb-tests.txt | 2 |
5 files changed, 237 insertions, 100 deletions
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 7f24f81c57..471ec29674 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -3444,106 +3444,95 @@ def t2ABS : PseudoInst<(outs rGPR:$dst), (ins rGPR:$src), //===----------------------------------------------------------------------===// // Coprocessor load/store -- for disassembly only // -class T2CI<dag oops, dag iops, string opc, string asm> +class T2CI<bits<4> op31_28, dag oops, dag iops, string opc, string asm> : T2I<oops, iops, NoItinerary, opc, asm, []> { + let Inst{31-28} = op31_28; let Inst{27-25} = 0b110; } -multiclass T2LdStCop<bits<4> op31_28, bit load, string opc> { - def _OFFSET : T2CI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - opc, "\tp$cop, cr$CRd, $addr"> { - let Inst{31-28} = op31_28; - let Inst{24} = 1; // P = 1 - let Inst{21} = 0; // W = 0 - let Inst{22} = 0; // D = 0 - let Inst{20} = load; - let DecoderMethod = "DecodeCopMemInstruction"; - } - - def _PRE : T2CI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - opc, "\tp$cop, cr$CRd, $addr!"> { - let Inst{31-28} = op31_28; - let Inst{24} = 1; // P = 1 - let Inst{21} = 1; // W = 1 - let Inst{22} = 0; // D = 0 - let Inst{20} = load; - let DecoderMethod = "DecodeCopMemInstruction"; - } - - def _POST : T2CI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - opc, "\tp$cop, cr$CRd, $addr"> { - let Inst{31-28} = op31_28; - let Inst{24} = 0; // P = 0 - let Inst{21} = 1; // W = 1 - let Inst{22} = 0; // D = 0 - let Inst{20} = load; - let DecoderMethod = "DecodeCopMemInstruction"; - } - - def _OPTION : T2CI<(outs), - (ins nohash_imm:$cop,nohash_imm:$CRd,GPR:$base, nohash_imm:$option), - opc, "\tp$cop, cr$CRd, [$base], \\{$option\\}"> { - let Inst{31-28} = op31_28; - let Inst{24} = 0; // P = 0 - let Inst{23} = 1; // U = 1 - let Inst{21} = 0; // W = 0 - let Inst{22} = 0; // D = 0 - let Inst{20} = load; - let DecoderMethod = "DecodeCopMemInstruction"; - } - - def L_OFFSET : T2CI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr"> { - let Inst{31-28} = op31_28; +multiclass t2LdStCop<bits<4> op31_28, bit load, bit Dbit, string asm> { + def _OFFSET : T2CI<op31_28, + (outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), + asm, "\t$cop, $CRd, $addr"> { + bits<13> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 1; // P = 1 + let Inst{23} = addr{8}; + let Inst{22} = Dbit; let Inst{21} = 0; // W = 0 - let Inst{22} = 1; // D = 1 let Inst{20} = load; + let Inst{19-16} = addr{12-9}; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = addr{7-0}; let DecoderMethod = "DecodeCopMemInstruction"; } - - def L_PRE : T2CI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> { - let Inst{31-28} = op31_28; + def _PRE : T2CI<op31_28, + (outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), + asm, "\t$cop, $CRd, $addr!"> { + bits<13> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 1; // P = 1 + let Inst{23} = addr{8}; + let Inst{22} = Dbit; let Inst{21} = 1; // W = 1 - let Inst{22} = 1; // D = 1 let Inst{20} = load; + let Inst{19-16} = addr{12-9}; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = addr{7-0}; let DecoderMethod = "DecodeCopMemInstruction"; } - - def L_POST : T2CI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd, addr_offset_none:$addr, - postidx_imm8s4:$offset), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr, $offset"> { - let Inst{31-28} = op31_28; + def _POST: T2CI<op31_28, + (outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, + postidx_imm8s4:$offset), + asm, "\t$cop, $CRd, $addr, $offset"> { + bits<9> offset; + bits<4> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 0; // P = 0 + let Inst{23} = offset{8}; + let Inst{22} = Dbit; let Inst{21} = 1; // W = 1 - let Inst{22} = 1; // D = 1 let Inst{20} = load; + let Inst{19-16} = addr; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = offset{7-0}; let DecoderMethod = "DecodeCopMemInstruction"; } - - def L_OPTION : T2CI<(outs), - (ins nohash_imm:$cop, nohash_imm:$CRd,GPR:$base,nohash_imm:$option), - !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], \\{$option\\}"> { - let Inst{31-28} = op31_28; + def _OPTION : T2CI<op31_28, (outs), + (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, + coproc_option_imm:$option), + asm, "\t$cop, $CRd, $addr, $option"> { + bits<8> option; + bits<4> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 0; // P = 0 let Inst{23} = 1; // U = 1 + let Inst{22} = Dbit; let Inst{21} = 0; // W = 0 - let Inst{22} = 1; // D = 1 let Inst{20} = load; + let Inst{19-16} = addr; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = option; let DecoderMethod = "DecodeCopMemInstruction"; } } -defm t2LDC : T2LdStCop<0b1111, 1, "ldc">; -defm t2STC : T2LdStCop<0b1111, 0, "stc">; +defm t2LDC : t2LdStCop<0b1110, 1, 0, "ldc">; +defm t2LDCL : t2LdStCop<0b1110, 1, 1, "ldcl">; +defm t2STC : t2LdStCop<0b1110, 0, 0, "stc">; +defm t2STCL : t2LdStCop<0b1110, 0, 1, "stcl">; +defm t2LDC2 : t2LdStCop<0b1111, 1, 0, "ldc2">; +defm t2LDC2L : t2LdStCop<0b1111, 1, 1, "ldc2l">; +defm t2STC2 : t2LdStCop<0b1111, 0, 0, "stc2">; +defm t2STC2L : t2LdStCop<0b1111, 0, 1, "stc2l">; //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 3ce086a049..24f15b4694 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -2086,7 +2086,8 @@ ARMAsmParser::OperandMatchResultTy ARMAsmParser:: parseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { SMLoc S = Parser.getTok().getLoc(); const AsmToken &Tok = Parser.getTok(); - assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); + if (Tok.isNot(AsmToken::Identifier)) + return MatchOperand_NoMatch; int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); if (Num == -1) @@ -2104,7 +2105,8 @@ ARMAsmParser::OperandMatchResultTy ARMAsmParser:: parseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { SMLoc S = Parser.getTok().getLoc(); const AsmToken &Tok = Parser.getTok(); - assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); + if (Tok.isNot(AsmToken::Identifier)) + return MatchOperand_NoMatch; int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); if (Reg == -1) diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 7576801f71..7cead8c13b 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -1244,34 +1244,60 @@ static DecodeStatus DecodeCopMemInstruction(llvm::MCInst &Inst, unsigned Insn, idx_mode = ARMII::IndexModePost; switch (Inst.getOpcode()) { - case ARM::LDCL_POST: - case ARM::STCL_POST: - case ARM::t2LDCL_POST: - case ARM::t2STCL_POST: + case ARM::t2LDC2_OFFSET: + case ARM::t2LDC2L_OFFSET: + case ARM::t2LDC2_PRE: + case ARM::t2LDC2L_PRE: + case ARM::t2LDC2_POST: + case ARM::t2LDC2L_POST: + case ARM::t2STC2_OFFSET: + case ARM::t2STC2L_OFFSET: + case ARM::t2STC2_PRE: + case ARM::t2STC2L_PRE: + case ARM::t2STC2_POST: + case ARM::t2STC2L_POST: + case ARM::LDC2_OFFSET: + case ARM::LDC2L_OFFSET: + case ARM::LDC2_PRE: + case ARM::LDC2L_PRE: + case ARM::LDC2_POST: case ARM::LDC2L_POST: + case ARM::STC2_OFFSET: + case ARM::STC2L_OFFSET: + case ARM::STC2_PRE: + case ARM::STC2L_PRE: + case ARM::STC2_POST: case ARM::STC2L_POST: + case ARM::t2LDC_OFFSET: + case ARM::t2LDCL_OFFSET: + case ARM::t2LDC_PRE: + case ARM::t2LDCL_PRE: + case ARM::t2LDC_POST: + case ARM::t2LDCL_POST: + case ARM::t2STC_OFFSET: + case ARM::t2STCL_OFFSET: + case ARM::t2STC_PRE: + case ARM::t2STCL_PRE: + case ARM::t2STC_POST: + case ARM::t2STCL_POST: + case ARM::LDC_OFFSET: + case ARM::LDCL_OFFSET: + case ARM::LDC_PRE: + case ARM::LDCL_PRE: + case ARM::LDC_POST: + case ARM::LDCL_POST: + case ARM::STC_OFFSET: + case ARM::STCL_OFFSET: + case ARM::STC_PRE: + case ARM::STCL_PRE: + case ARM::STC_POST: + case ARM::STCL_POST: imm |= U << 8; - case ARM::LDC_OPTION: - case ARM::LDCL_OPTION: - case ARM::LDC2_OPTION: - case ARM::LDC2L_OPTION: - case ARM::STC_OPTION: - case ARM::STCL_OPTION: - case ARM::STC2_OPTION: - case ARM::STC2L_OPTION: - case ARM::t2LDC_OPTION: - case ARM::t2LDCL_OPTION: - case ARM::t2STC_OPTION: - case ARM::t2STCL_OPTION: - Inst.addOperand(MCOperand::CreateImm(imm)); - break; + // fall through. default: - if (U) - Inst.addOperand(MCOperand::CreateImm( - ARM_AM::getAM2Opc(ARM_AM::add, imm, ARM_AM::lsl, idx_mode))); - else - Inst.addOperand(MCOperand::CreateImm( - ARM_AM::getAM2Opc(ARM_AM::sub, imm, ARM_AM::lsl, idx_mode))); + // The 'option' variant doesn't encode 'U' in the immediate since + // the immediate is unsigned [0,255]. + Inst.addOperand(MCOperand::CreateImm(imm)); break; } diff --git a/test/MC/ARM/basic-thumb2-instructions.s b/test/MC/ARM/basic-thumb2-instructions.s index c2e78e71f8..68815dab01 100644 --- a/test/MC/ARM/basic-thumb2-instructions.s +++ b/test/MC/ARM/basic-thumb2-instructions.s @@ -495,6 +495,66 @@ _func: @------------------------------------------------------------------------------ +@ LDC{L}/LDC2{L} +@------------------------------------------------------------------------------ + ldc2 p0, c8, [r1, #4] + ldc2 p1, c7, [r2] + ldc2 p2, c6, [r3, #-224] + ldc2 p3, c5, [r4, #-120]! + ldc2 p4, c4, [r5], #16 + ldc2 p5, c3, [r6], #-72 + ldc2l p6, c2, [r7, #4] + ldc2l p7, c1, [r8] + ldc2l p8, c0, [r9, #-224] + ldc2l p9, c1, [r10, #-120]! + ldc2l p10, c2, [r11], #16 + ldc2l p11, c3, [r12], #-72 + + ldc p12, c4, [r0, #4] + ldc p13, c5, [r1] + ldc p14, c6, [r2, #-224] + ldc p15, c7, [r3, #-120]! + ldc p5, c8, [r4], #16 + ldc p4, c9, [r5], #-72 + ldcl p3, c10, [r6, #4] + ldcl p2, c11, [r7] + ldcl p1, c12, [r8, #-224] + ldcl p0, c13, [r9, #-120]! + ldcl p6, c14, [r10], #16 + ldcl p7, c15, [r11], #-72 + + ldc2 p2, c8, [r1], { 25 } + +@ CHECK: ldc2 p0, c8, [r1, #4] @ encoding: [0x91,0xfd,0x01,0x80] +@ CHECK: ldc2 p1, c7, [r2] @ encoding: [0x92,0xfd,0x00,0x71] +@ CHECK: ldc2 p2, c6, [r3, #-224] @ encoding: [0x13,0xfd,0x38,0x62] +@ CHECK: ldc2 p3, c5, [r4, #-120]! @ encoding: [0x34,0xfd,0x1e,0x53] +@ CHECK: ldc2 p4, c4, [r5], #16 @ encoding: [0xb5,0xfc,0x04,0x44] +@ CHECK: ldc2 p5, c3, [r6], #-72 @ encoding: [0x36,0xfc,0x12,0x35] +@ CHECK: ldc2l p6, c2, [r7, #4] @ encoding: [0xd7,0xfd,0x01,0x26] +@ CHECK: ldc2l p7, c1, [r8] @ encoding: [0xd8,0xfd,0x00,0x17] +@ CHECK: ldc2l p8, c0, [r9, #-224] @ encoding: [0x59,0xfd,0x38,0x08] +@ CHECK: ldc2l p9, c1, [r10, #-120]! @ encoding: [0x7a,0xfd,0x1e,0x19] +@ CHECK: ldc2l p10, c2, [r11], #16 @ encoding: [0xfb,0xfc,0x04,0x2a] +@ CHECK: ldc2l p11, c3, [r12], #-72 @ encoding: [0x7c,0xfc,0x12,0x3b] + +@ CHECK: ldc p12, c4, [r0, #4] @ encoding: [0x90,0xed,0x01,0x4c] +@ CHECK: ldc p13, c5, [r1] @ encoding: [0x91,0xed,0x00,0x5d] +@ CHECK: ldc p14, c6, [r2, #-224] @ encoding: [0x12,0xed,0x38,0x6e] +@ CHECK: ldc p15, c7, [r3, #-120]! @ encoding: [0x33,0xed,0x1e,0x7f] +@ CHECK: ldc p5, c8, [r4], #16 @ encoding: [0xb4,0xec,0x04,0x85] +@ CHECK: ldc p4, c9, [r5], #-72 @ encoding: [0x35,0xec,0x12,0x94] +@ CHECK: ldcl p3, c10, [r6, #4] @ encoding: [0xd6,0xed,0x01,0xa3] +@ CHECK: ldcl p2, c11, [r7] @ encoding: [0xd7,0xed,0x00,0xb2] +@ CHECK: ldcl p1, c12, [r8, #-224] @ encoding: [0x58,0xed,0x38,0xc1] +@ CHECK: ldcl p0, c13, [r9, #-120]! @ encoding: [0x79,0xed,0x1e,0xd0] +@ CHECK: ldcl p6, c14, [r10], #16 @ encoding: [0xfa,0xec,0x04,0xe6] +@ CHECK: ldcl p7, c15, [r11], #-72 @ encoding: [0x7b,0xec,0x12,0xf7] + +@ CHECK: ldc2 p2, c8, [r1], {25} @ encoding: [0x91,0xfc,0x19,0x82] + + +@------------------------------------------------------------------------------ @ LDMIA @------------------------------------------------------------------------------ ldmia.w r4, {r4, r5, r8, r9} @@ -2123,6 +2183,66 @@ _func: @------------------------------------------------------------------------------ +@ STC{L}/STC2{L} +@------------------------------------------------------------------------------ + stc2 p0, c8, [r1, #4] + stc2 p1, c7, [r2] + stc2 p2, c6, [r3, #-224] + stc2 p3, c5, [r4, #-120]! + stc2 p4, c4, [r5], #16 + stc2 p5, c3, [r6], #-72 + stc2l p6, c2, [r7, #4] + stc2l p7, c1, [r8] + stc2l p8, c0, [r9, #-224] + stc2l p9, c1, [r10, #-120]! + stc2l p10, c2, [r11], #16 + stc2l p11, c3, [r12], #-72 + + stc p12, c4, [r0, #4] + stc p13, c5, [r1] + stc p14, c6, [r2, #-224] + stc p15, c7, [r3, #-120]! + stc p5, c8, [r4], #16 + stc p4, c9, [r5], #-72 + stcl p3, c10, [r6, #4] + stcl p2, c11, [r7] + stcl p1, c12, [r8, #-224] + stcl p0, c13, [r9, #-120]! + stcl p6, c14, [r10], #16 + stcl p7, c15, [r11], #-72 + + stc2 p2, c8, [r1], { 25 } + +@ CHECK: stc2 p0, c8, [r1, #4] @ encoding: [0x81,0xfd,0x01,0x80] +@ CHECK: stc2 p1, c7, [r2] @ encoding: [0x82,0xfd,0x00,0x71] +@ CHECK: stc2 p2, c6, [r3, #-224] @ encoding: [0x03,0xfd,0x38,0x62] +@ CHECK: stc2 p3, c5, [r4, #-120]! @ encoding: [0x24,0xfd,0x1e,0x53] +@ CHECK: stc2 p4, c4, [r5], #16 @ encoding: [0xa5,0xfc,0x04,0x44] +@ CHECK: stc2 p5, c3, [r6], #-72 @ encoding: [0x26,0xfc,0x12,0x35] +@ CHECK: stc2l p6, c2, [r7, #4] @ encoding: [0xc7,0xfd,0x01,0x26] +@ CHECK: stc2l p7, c1, [r8] @ encoding: [0xc8,0xfd,0x00,0x17] +@ CHECK: stc2l p8, c0, [r9, #-224] @ encoding: [0x49,0xfd,0x38,0x08] +@ CHECK: stc2l p9, c1, [r10, #-120]! @ encoding: [0x6a,0xfd,0x1e,0x19] +@ CHECK: stc2l p10, c2, [r11], #16 @ encoding: [0xeb,0xfc,0x04,0x2a] +@ CHECK: stc2l p11, c3, [r12], #-72 @ encoding: [0x6c,0xfc,0x12,0x3b] + +@ CHECK: stc p12, c4, [r0, #4] @ encoding: [0x80,0xed,0x01,0x4c] +@ CHECK: stc p13, c5, [r1] @ encoding: [0x81,0xed,0x00,0x5d] +@ CHECK: stc p14, c6, [r2, #-224] @ encoding: [0x02,0xed,0x38,0x6e] +@ CHECK: stc p15, c7, [r3, #-120]! @ encoding: [0x23,0xed,0x1e,0x7f] +@ CHECK: stc p5, c8, [r4], #16 @ encoding: [0xa4,0xec,0x04,0x85] +@ CHECK: stc p4, c9, [r5], #-72 @ encoding: [0x25,0xec,0x12,0x94] +@ CHECK: stcl p3, c10, [r6, #4] @ encoding: [0xc6,0xed,0x01,0xa3] +@ CHECK: stcl p2, c11, [r7] @ encoding: [0xc7,0xed,0x00,0xb2] +@ CHECK: stcl p1, c12, [r8, #-224] @ encoding: [0x48,0xed,0x38,0xc1] +@ CHECK: stcl p0, c13, [r9, #-120]! @ encoding: [0x69,0xed,0x1e,0xd0] +@ CHECK: stcl p6, c14, [r10], #16 @ encoding: [0xea,0xec,0x04,0xe6] +@ CHECK: stcl p7, c15, [r11], #-72 @ encoding: [0x6b,0xec,0x12,0xf7] + +@ CHECK: stc2 p2, c8, [r1], {25} @ encoding: [0x81,0xfc,0x19,0x82] + + +@------------------------------------------------------------------------------ @ STMIA @------------------------------------------------------------------------------ stmia.w r4, {r4, r5, r8, r9} diff --git a/test/MC/Disassembler/ARM/thumb-tests.txt b/test/MC/Disassembler/ARM/thumb-tests.txt index c8b7e117de..18b8f4701d 100644 --- a/test/MC/Disassembler/ARM/thumb-tests.txt +++ b/test/MC/Disassembler/ARM/thumb-tests.txt @@ -218,7 +218,7 @@ # CHECK: pld [r5, #30] 0x95 0xf8 0x1e 0xf0 -# CHECK: stc p12, cr15, [r9], {137} +# CHECK: stc2 p12, c15, [r9], {137} 0x89 0xfc 0x89 0xfc # CHECK: vmov r1, r0, d11 |