llvm.org GIT mirror llvm / 584bf7b
Add assembly parsing support for "msr" and also fix its encoding. Also add testcases for the disassembler to make sure it still works for "msr". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125948 91177308-0d34-0410-b5e6-96231b3b80d8 Bruno Cardoso Lopes 9 years ago
11 changed file(s) with 242 addition(s) and 53 deletion(s). Raw diff Collapse all Expand all
160160 let ParserMethod = "tryParseProcIFlagsOperand";
161161 }
162162
163 def MSRMaskOperand : AsmOperandClass {
164 let Name = "MSRMask";
165 let SuperClasses = [];
166 let ParserMethod = "tryParseMSRMaskOperand";
167 }
168
163169 // ARM imod and iflag operands, used only by the CPS instruction.
164170 def imod_op : Operand {
165171 let PrintMethod = "printCPSIMod";
204210
205211 def msr_mask : Operand {
206212 let PrintMethod = "printMSRMaskOperand";
213 let ParserMatchClass = MSRMaskOperand;
207214 }
208215
209216 // A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
38553855 // Move between special register and ARM core register -- for disassembly only
38563856 //
38573857
3858 // Move to ARM core register from Special Register
38583859 def MRS : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, cpsr",
38593860 [/* For disassembly only; pattern left blank */]> {
38603861 bits<4> Rd;
38713872 let Inst{7-4} = 0b0000;
38723873 }
38733874
3874 def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3875 "msr", "\tcpsr$mask, $src",
3875 // Move from ARM core register to Special Register
3876 //
3877 // No need to have both system and application versions, the encodings are the
3878 // same and the assembly parser has no way to distinguish between them. The mask
3879 // operand contains the special register (R Bit) in bit 4 and bits 3-0 contains
3880 // the mask with the fields to be accessed in the special register.
3881 def MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary,
3882 "msr", "\t$mask, $Rn",
38763883 [/* For disassembly only; pattern left blank */]> {
3877 let Inst{23-20} = 0b0010;
3878 let Inst{7-4} = 0b0000;
3879 }
3880
3881 def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3882 "msr", "\tcpsr$mask, $a",
3883 [/* For disassembly only; pattern left blank */]> {
3884 let Inst{23-20} = 0b0010;
3885 let Inst{7-4} = 0b0000;
3886 }
3887
3888 def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
3889 "msr", "\tspsr$mask, $src",
3890 [/* For disassembly only; pattern left blank */]> {
3891 let Inst{23-20} = 0b0110;
3892 let Inst{7-4} = 0b0000;
3893 }
3894
3895 def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
3896 "msr", "\tspsr$mask, $a",
3897 [/* For disassembly only; pattern left blank */]> {
3898 let Inst{23-20} = 0b0110;
3899 let Inst{7-4} = 0b0000;
3900 }
3884 bits<5> mask;
3885 bits<4> Rn;
3886
3887 let Inst{23} = 0;
3888 let Inst{22} = mask{4}; // R bit
3889 let Inst{21-20} = 0b10;
3890 let Inst{19-16} = mask{3-0};
3891 let Inst{15-12} = 0b1111;
3892 let Inst{11-4} = 0b00000000;
3893 let Inst{3-0} = Rn;
3894 }
3895
3896 def MSRi : ABI<0b0011, (outs), (ins msr_mask:$mask, so_imm:$a), NoItinerary,
3897 "msr", "\t$mask, $a",
3898 [/* For disassembly only; pattern left blank */]> {
3899 bits<5> mask;
3900 bits<12> a;
3901
3902 let Inst{23} = 0;
3903 let Inst{22} = mask{4}; // R bit
3904 let Inst{21-20} = 0b10;
3905 let Inst{19-16} = mask{3-0};
3906 let Inst{15-12} = 0b1111;
3907 let Inst{11-0} = a;
3908 }
33293329 (outs rGPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, spsr",
33303330 [/* For disassembly only; pattern left blank */]>;
33313331
3332 class T2MSR op31_20, bits<2> op15_14, bits<1> op12,
3333 dag oops, dag iops, InstrItinClass itin,
3334 string opc, string asm, list pattern>
3335 : T2SpecialReg {
3332 // Move from ARM core register to Special Register
3333 //
3334 // No need to have both system and application versions, the encodings are the
3335 // same and the assembly parser has no way to distinguish between them. The mask
3336 // operand contains the special register (R Bit) in bit 4 and bits 3-0 contains
3337 // the mask with the fields to be accessed in the special register.
3338 def t2MSR : T2SpecialReg<0b111100111000 /* op31-20 */, 0b10 /* op15-14 */,
3339 0 /* op12 */, (outs), (ins msr_mask:$mask, rGPR:$Rn),
3340 NoItinerary, "msr", "\t$mask, $Rn",
3341 [/* For disassembly only; pattern left blank */]> {
3342 bits<5> mask;
33363343 bits<4> Rn;
3337 bits<4> mask;
33383344 let Inst{19-16} = Rn;
3339 let Inst{11-8} = mask;
3340 }
3341
3342 def t2MSR : T2MSR<0b111100111000, 0b10, 0,
3343 (outs), (ins rGPR:$Rn, msr_mask:$mask), NoItinerary, "msr",
3344 "\tcpsr$mask, $Rn",
3345 [/* For disassembly only; pattern left blank */]>;
3346 def t2MSRsys : T2MSR<0b111100111001, 0b10, 0,
3347 (outs), (ins rGPR:$Rn, msr_mask:$mask), NoItinerary, "msr",
3348 "\tspsr$mask, $Rn",
3349 [/* For disassembly only; pattern left blank */]>;
3345 let Inst{20} = mask{4}; // R Bit
3346 let Inst{13} = 0b0;
3347 let Inst{11-8} = mask{3-0};
3348 }
33503349
33513350 //===----------------------------------------------------------------------===//
33523351 // Move between coprocessor and ARM core register -- for disassembly only
9999 SmallVectorImpl &);
100100 OperandMatchResultTy tryParseProcIFlagsOperand(
101101 SmallVectorImpl &);
102 OperandMatchResultTy tryParseMSRMaskOperand(
103 SmallVectorImpl &);
102104
103105 public:
104106 ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
127129 Immediate,
128130 MemBarrierOpt,
129131 Memory,
132 MSRMask,
130133 ProcIFlags,
131134 Register,
132135 RegisterList,
154157 struct {
155158 ARM_PROC::IFlags Val;
156159 } IFlags;
160
161 struct {
162 unsigned Val;
163 } MMask;
157164
158165 struct {
159166 const char *Data;
221228 case Memory:
222229 Mem = o.Mem;
223230 break;
231 case MSRMask:
232 MMask = o.MMask;
233 break;
224234 case ProcIFlags:
225235 IFlags = o.IFlags;
226236 }
270280 ARM_PROC::IFlags getProcIFlags() const {
271281 assert(Kind == ProcIFlags && "Invalid access!");
272282 return IFlags.Val;
283 }
284
285 unsigned getMSRMask() const {
286 assert(Kind == MSRMask && "Invalid access!");
287 return MMask.Val;
273288 }
274289
275290 /// @name Memory Operand Accessors
346361 uint64_t Value = CE->getValue();
347362 return ((Value & 0x3) == 0 && Value <= 124);
348363 }
364 bool isMSRMask() const { return Kind == MSRMask; }
349365 bool isProcIFlags() const { return Kind == ProcIFlags; }
350366
351367 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
445461 const MCConstantExpr *CE = dyn_cast(getMemOffset());
446462 assert(CE && "Non-constant mode offset operand!");
447463 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
464 }
465
466 void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
467 assert(N == 1 && "Invalid number of operands!");
468 Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
448469 }
449470
450471 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
583604 Op->EndLoc = S;
584605 return Op;
585606 }
607
608 static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
609 ARMOperand *Op = new ARMOperand(MSRMask);
610 Op->MMask.Val = MMask;
611 Op->StartLoc = S;
612 Op->EndLoc = S;
613 return Op;
614 }
586615 };
587616
588617 } // end anonymous namespace.
600629 break;
601630 case CoprocReg:
602631 OS << "";
632 break;
633 case MSRMask:
634 OS << "";
603635 break;
604636 case Immediate:
605637 getImm()->print(OS);
946978
947979 Parser.Lex(); // Eat identifier token.
948980 Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
981 return MatchOperand_Success;
982 }
983
984 /// tryParseMSRMaskOperand - Try to parse mask flags from MSR instruction.
985 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
986 tryParseMSRMaskOperand(SmallVectorImpl &Operands) {
987 SMLoc S = Parser.getTok().getLoc();
988 const AsmToken &Tok = Parser.getTok();
989 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
990 StringRef Mask = Tok.getString();
991
992 // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
993 size_t Start = 0, Next = Mask.find('_');
994 StringRef Flags = "";
995 StringRef SpecReg = Mask.slice(Start, Next);
996 if (Next != StringRef::npos)
997 Flags = Mask.slice(Next+1, Mask.size());
998
999 // FlagsVal contains the complete mask:
1000 // 3-0: Mask
1001 // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1002 unsigned FlagsVal = 0;
1003
1004 if (SpecReg == "apsr") {
1005 FlagsVal = StringSwitch(Flags)
1006 .Case("nzcvq", 0x8) // same as CPSR_c
1007 .Case("g", 0x4) // same as CPSR_s
1008 .Case("nzcvqg", 0xc) // same as CPSR_fs
1009 .Default(~0U);
1010
1011 if (FlagsVal == ~0U)
1012 if (!Flags.empty())
1013 return MatchOperand_NoMatch;
1014 else
1015 FlagsVal = 0; // No flag
1016 } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
1017 for (int i = 0, e = Flags.size(); i != e; ++i) {
1018 unsigned Flag = StringSwitch(Flags.substr(i, 1))
1019 .Case("c", 1)
1020 .Case("x", 2)
1021 .Case("s", 4)
1022 .Case("f", 8)
1023 .Default(~0U);
1024
1025 // If some specific flag is already set, it means that some letter is
1026 // present more than once, this is not acceptable.
1027 if (FlagsVal == ~0U || (FlagsVal & Flag))
1028 return MatchOperand_NoMatch;
1029 FlagsVal |= Flag;
1030 }
1031 } else // No match for special register.
1032 return MatchOperand_NoMatch;
1033
1034 // Special register without flags are equivalent to "fc" flags.
1035 if (!FlagsVal)
1036 FlagsVal = 0x9;
1037
1038 // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1039 if (SpecReg == "spsr")
1040 FlagsVal |= 16;
1041
1042 Parser.Lex(); // Eat identifier token.
1043 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
9491044 return MatchOperand_Success;
9501045 }
9511046
719719 NumOpsAdded = 1;
720720 return true;
721721 }
722 // MSR and MSRsys take one GPR reg Rm, followed by the mask.
723 if (Opcode == ARM::MSR || Opcode == ARM::MSRsys) {
724 assert(NumOps >= 1 && OpInfo[0].RegClass == ARM::GPRRegClassID &&
722 // MSR take a mask, followed by one GPR reg Rm. The mask contains the R Bit in
723 // bit 4, and the special register fields in bits 3-0.
724 if (Opcode == ARM::MSR) {
725 assert(NumOps >= 1 && OpInfo[1].RegClass == ARM::GPRRegClassID &&
725726 "Reg operand expected");
727 MI.addOperand(MCOperand::CreateImm(slice(insn, 22, 22) << 4 /* R Bit */ |
728 slice(insn, 19, 16) /* Special Reg */ ));
726729 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
727730 decodeRm(insn))));
728 MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 16)));
729731 NumOpsAdded = 2;
730732 return true;
731733 }
732 // MSRi and MSRsysi take one so_imm operand, followed by the mask.
733 if (Opcode == ARM::MSRi || Opcode == ARM::MSRsysi) {
734 // MSRi take a mask, followed by one so_imm operand. The mask contains the
735 // R Bit in bit 4, and the special register fields in bits 3-0.
736 if (Opcode == ARM::MSRi) {
737 MI.addOperand(MCOperand::CreateImm(slice(insn, 22, 22) << 4 /* R Bit */ |
738 slice(insn, 19, 16) /* Special Reg */ ));
734739 // SOImm is 4-bit rotate amount in bits 11-8 with 8-bit imm in bits 7-0.
735740 // A5.2.4 Rotate amount is twice the numeric value of Inst{11-8}.
736741 // See also ARMAddressingModes.h: getSOImmValImm() and getSOImmValRot().
737742 unsigned Rot = (insn >> ARMII::SoRotImmShift) & 0xF;
738743 unsigned Imm = insn & 0xFF;
739744 MI.addOperand(MCOperand::CreateImm(ARM_AM::rotr32(Imm, 2*Rot)));
740 MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 16)));
741745 NumOpsAdded = 2;
742746 return true;
743747 }
17011701 NumOpsAdded = 1;
17021702 return true;
17031703 }
1704 // MSR and MSRsys take one GPR reg Rn, followed by the mask.
1705 if (Opcode == ARM::t2MSR || Opcode == ARM::t2MSRsys || Opcode == ARM::t2BXJ) {
1704 // MSR take a mask, followed by one GPR reg Rn. The mask contains the R Bit in
1705 // bit 4, and the special register fields in bits 3-0.
1706 if (Opcode == ARM::t2MSR) {
1707 MI.addOperand(MCOperand::CreateImm(slice(insn, 20, 20) << 4 /* R Bit */ |
1708 slice(insn, 11, 8) /* Special Reg */));
17061709 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
17071710 decodeRn(insn))));
1708 MI.addOperand(MCOperand::CreateImm(slice(insn, 11, 8)));
17091711 NumOpsAdded = 2;
17101712 return true;
17111713 }
396396 void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
397397 raw_ostream &O) {
398398 const MCOperand &Op = MI->getOperand(OpNum);
399 unsigned Mask = Op.getImm();
399 unsigned SpecRegRBit = Op.getImm() >> 4;
400 unsigned Mask = Op.getImm() & 0xf;
401
402 if (SpecRegRBit)
403 O << "spsr";
404 else
405 O << "cpsr";
406
400407 if (Mask) {
401408 O << '_';
402409 if (Mask & 8) O << 'f';
245245 @ CHECK: cpsie if, #10 @ encoding: [0xca,0x00,0x0a,0xf1]
246246 cpsie if, #10
247247
248 @ CHECK: msr cpsr_fc, r0 @ encoding: [0x00,0xf0,0x29,0xe1]
249 msr apsr, r0
250
251 @ CHECK: msr cpsr_s, r0 @ encoding: [0x00,0xf0,0x24,0xe1]
252 msr apsr_g, r0
253
254 @ CHECK: msr cpsr_f, r0 @ encoding: [0x00,0xf0,0x28,0xe1]
255 msr apsr_nzcvq, r0
256
257 @ CHECK: msr cpsr_fs, r0 @ encoding: [0x00,0xf0,0x2c,0xe1]
258 msr apsr_nzcvqg, r0
259
260 @ CHECK: msr cpsr_fc, r0 @ encoding: [0x00,0xf0,0x29,0xe1]
261 msr cpsr_fc, r0
262
263 @ CHECK: msr cpsr_c, r0 @ encoding: [0x00,0xf0,0x21,0xe1]
264 msr cpsr_c, r0
265
266 @ CHECK: msr cpsr_x, r0 @ encoding: [0x00,0xf0,0x22,0xe1]
267 msr cpsr_x, r0
268
269 @ CHECK: msr cpsr_fc, r0 @ encoding: [0x00,0xf0,0x29,0xe1]
270 msr cpsr_fc, r0
271
272 @ CHECK: msr cpsr_fsx, r0 @ encoding: [0x00,0xf0,0x2e,0xe1]
273 msr cpsr_fsx, r0
274
275 @ CHECK: msr spsr_fc, r0 @ encoding: [0x00,0xf0,0x69,0xe1]
276 msr spsr_fc, r0
277
278 @ CHECK: msr spsr_fsxc, r0 @ encoding: [0x00,0xf0,0x6f,0xe1]
279 msr spsr_fsxc, r0
280
281 @ CHECK: msr cpsr_fsxc, r0 @ encoding: [0x00,0xf0,0x2f,0xe1]
282 msr cpsr_fsxc, r0
283
258258 @ CHECK: cpsie.w if, #10 @ encoding: [0xaf,0xf3,0x6a,0x85]
259259 cpsie.w if, #10
260260
261 @ CHECK: msr cpsr_fc, r0 @ encoding: [0x80,0xf3,0x00,0x89]
262 msr apsr, r0
263 @ CHECK: msr cpsr_s, r0 @ encoding: [0x80,0xf3,0x00,0x84]
264 msr apsr_g, r0
265 @ CHECK: msr cpsr_f, r0 @ encoding: [0x80,0xf3,0x00,0x88]
266 msr apsr_nzcvq, r0
267 @ CHECK: msr cpsr_fs, r0 @ encoding: [0x80,0xf3,0x00,0x8c]
268 msr apsr_nzcvqg, r0
269 @ CHECK: msr cpsr_fc, r0 @ encoding: [0x80,0xf3,0x00,0x89]
270 msr cpsr_fc, r0
271 @ CHECK: msr cpsr_c, r0 @ encoding: [0x80,0xf3,0x00,0x81]
272 msr cpsr_c, r0
273 @ CHECK: msr cpsr_x, r0 @ encoding: [0x80,0xf3,0x00,0x82]
274 msr cpsr_x, r0
275 @ CHECK: msr cpsr_fc, r0 @ encoding: [0x80,0xf3,0x00,0x89]
276 msr cpsr_fc, r0
277 @ CHECK: msr cpsr_fsx, r0 @ encoding: [0x80,0xf3,0x00,0x8e]
278 msr cpsr_fsx, r0
279 @ CHECK: msr spsr_fc, r0 @ encoding: [0x90,0xf3,0x00,0x89]
280 msr spsr_fc, r0
281 @ CHECK: msr spsr_fsxc, r0 @ encoding: [0x90,0xf3,0x00,0x8f]
282 msr spsr_fsxc, r0
283 @ CHECK: msr cpsr_fsxc, r0 @ encoding: [0x80,0xf3,0x00,0x8f]
284 msr cpsr_fsxc, r0
285
126126
127127 # CHECK: cpsie if, #10
128128 0xca 0x00 0x0a 0xf1
129
130 # CHECK: msr cpsr_fc, r0
131 0x00 0xf0 0x29 0xe1
114114
115115 # CHECK: cpsie aif
116116 0x67 0xb6
117
118 # CHECK: msr cpsr_fc, r0
119 0x80 0xf3 0x00 0x89