llvm.org GIT mirror llvm / 4e9a96d
ARM: ISB cannot be passed the same options as DMB ISB should only accepts full system sync, other options are reserved git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183656 91177308-0d34-0410-b5e6-96231b3b80d8 Amaury de la Vieuville 7 years ago
13 changed file(s) with 179 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
42124212 let DecoderMethod = "DecodeMemBarrierOption";
42134213 }
42144214
4215 def InstSyncBarrierOptOperand : AsmOperandClass {
4216 let Name = "InstSyncBarrierOpt";
4217 let ParserMethod = "parseInstSyncBarrierOptOperand";
4218 }
4219 def instsyncb_opt : Operand {
4220 let PrintMethod = "printInstSyncBOption";
4221 let ParserMatchClass = InstSyncBarrierOptOperand;
4222 let DecoderMethod = "DecodeInstSyncBarrierOption";
4223 }
4224
42154225 // memory barriers protect the atomic sequences
42164226 let hasSideEffects = 1 in {
42174227 def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
42324242 }
42334243
42344244 // ISB has only full system option
4235 def ISB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
4245 def ISB : AInoP<(outs), (ins instsyncb_opt:$opt), MiscFrm, NoItinerary,
42364246 "isb", "\t$opt", []>,
42374247 Requires<[IsARM, HasDB]> {
42384248 bits<4> opt;
31083108 let Inst{3-0} = opt;
31093109 }
31103110
3111 def t2ISB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
3111 def t2ISB : AInoP<(outs), (ins instsyncb_opt:$opt), ThumbFrm, NoItinerary,
31123112 "isb", "\t$opt",
31133113 []>, Requires<[IsThumb, HasDB]> {
31143114 bits<4> opt;
181181 OperandMatchResultTy parseCoprocOptionOperand(
182182 SmallVectorImpl&);
183183 OperandMatchResultTy parseMemBarrierOptOperand(
184 SmallVectorImpl&);
185 OperandMatchResultTy parseInstSyncBarrierOptOperand(
184186 SmallVectorImpl&);
185187 OperandMatchResultTy parseProcIFlagsOperand(
186188 SmallVectorImpl&);
314316 k_CoprocOption,
315317 k_Immediate,
316318 k_MemBarrierOpt,
319 k_InstSyncBarrierOpt,
317320 k_Memory,
318321 k_PostIndexRegister,
319322 k_MSRMask,
357360 ARM_MB::MemBOpt Val;
358361 };
359362
363 struct ISBOptOp {
364 ARM_ISB::InstSyncBOpt Val;
365 };
366
360367 struct IFlagsOp {
361368 ARM_PROC::IFlags Val;
362369 };
443450 struct CopOp Cop;
444451 struct CoprocOptionOp CoprocOption;
445452 struct MBOptOp MBOpt;
453 struct ISBOptOp ISBOpt;
446454 struct ITMaskOp ITMask;
447455 struct IFlagsOp IFlags;
448456 struct MMaskOp MMask;
503511 case k_MemBarrierOpt:
504512 MBOpt = o.MBOpt;
505513 break;
514 case k_InstSyncBarrierOpt:
515 ISBOpt = o.ISBOpt;
506516 case k_Memory:
507517 Memory = o.Memory;
508518 break;
585595 return MBOpt.Val;
586596 }
587597
598 ARM_ISB::InstSyncBOpt getInstSyncBarrierOpt() const {
599 assert(Kind == k_InstSyncBarrierOpt && "Invalid access!");
600 return ISBOpt.Val;
601 }
602
588603 ARM_PROC::IFlags getProcIFlags() const {
589604 assert(Kind == k_ProcIFlags && "Invalid access!");
590605 return IFlags.Val;
924939 bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
925940 bool isToken() const { return Kind == k_Token; }
926941 bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
942 bool isInstSyncBarrierOpt() const { return Kind == k_InstSyncBarrierOpt; }
927943 bool isMem() const { return Kind == k_Memory; }
928944 bool isShifterImm() const { return Kind == k_ShifterImmediate; }
929945 bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; }
16991715 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
17001716 assert(N == 1 && "Invalid number of operands!");
17011717 Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
1718 }
1719
1720 void addInstSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
1721 assert(N == 1 && "Invalid number of operands!");
1722 Inst.addOperand(MCOperand::CreateImm(unsigned(getInstSyncBarrierOpt())));
17021723 }
17031724
17041725 void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
23662387 return Op;
23672388 }
23682389
2390 static ARMOperand *CreateInstSyncBarrierOpt(ARM_ISB::InstSyncBOpt Opt,
2391 SMLoc S) {
2392 ARMOperand *Op = new ARMOperand(k_InstSyncBarrierOpt);
2393 Op->ISBOpt.Val = Opt;
2394 Op->StartLoc = S;
2395 Op->EndLoc = S;
2396 return Op;
2397 }
2398
23692399 static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
23702400 ARMOperand *Op = new ARMOperand(k_ProcIFlags);
23712401 Op->IFlags.Val = IFlags;
24192449 break;
24202450 case k_MemBarrierOpt:
24212451 OS << "";
2452 break;
2453 case k_InstSyncBarrierOpt:
2454 OS << "";
24222455 break;
24232456 case k_Memory:
24242457 OS << "
34043437 return MatchOperand_Success;
34053438 }
34063439
3440 /// parseInstSyncBarrierOptOperand - Try to parse ISB inst sync barrier options.
3441 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
3442 parseInstSyncBarrierOptOperand(SmallVectorImpl &Operands) {
3443 SMLoc S = Parser.getTok().getLoc();
3444 const AsmToken &Tok = Parser.getTok();
3445 unsigned Opt;
3446
3447 if (Tok.is(AsmToken::Identifier)) {
3448 StringRef OptStr = Tok.getString();
3449
3450 if (OptStr.lower() == "sy")
3451 Opt = ARM_ISB::SY;
3452 else
3453 return MatchOperand_NoMatch;
3454
3455 Parser.Lex(); // Eat identifier token.
3456 } else if (Tok.is(AsmToken::Hash) ||
3457 Tok.is(AsmToken::Dollar) ||
3458 Tok.is(AsmToken::Integer)) {
3459 if (Parser.getTok().isNot(AsmToken::Integer))
3460 Parser.Lex(); // Eat the '#'.
3461 SMLoc Loc = Parser.getTok().getLoc();
3462
3463 const MCExpr *ISBarrierID;
3464 if (getParser().parseExpression(ISBarrierID)) {
3465 Error(Loc, "illegal expression");
3466 return MatchOperand_ParseFail;
3467 }
3468
3469 const MCConstantExpr *CE = dyn_cast(ISBarrierID);
3470 if (!CE) {
3471 Error(Loc, "constant expression expected");
3472 return MatchOperand_ParseFail;
3473 }
3474
3475 int Val = CE->getValue();
3476 if (Val & ~0xf) {
3477 Error(Loc, "immediate value out of range");
3478 return MatchOperand_ParseFail;
3479 }
3480
3481 Opt = ARM_ISB::RESERVED_0 + Val;
3482 } else
3483 return MatchOperand_ParseFail;
3484
3485 Operands.push_back(ARMOperand::CreateInstSyncBarrierOpt(
3486 (ARM_ISB::InstSyncBOpt)Opt, S));
3487 return MatchOperand_Success;
3488 }
3489
3490
34073491 /// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
34083492 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
34093493 parseProcIFlagsOperand(SmallVectorImpl &Operands) {
277277 static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn,
278278 uint64_t Address, const void *Decoder);
279279 static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn,
280 uint64_t Address, const void *Decoder);
281 static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Insn,
280282 uint64_t Address, const void *Decoder);
281283 static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn,
282284 uint64_t Address, const void *Decoder);
35523554 return MCDisassembler::Success;
35533555 }
35543556
3557 static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Val,
3558 uint64_t Address, const void *Decoder) {
3559 if (Val & ~0xf)
3560 return MCDisassembler::Fail;
3561
3562 Inst.addOperand(MCOperand::CreateImm(Val));
3563 return MCDisassembler::Success;
3564 }
3565
35553566 static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
35563567 uint64_t Address, const void *Decoder) {
35573568 if (!Val) return MCDisassembler::Fail;
671671 raw_ostream &O) {
672672 unsigned val = MI->getOperand(OpNum).getImm();
673673 O << ARM_MB::MemBOptToString(val);
674 }
675
676 void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum,
677 raw_ostream &O) {
678 unsigned val = MI->getOperand(OpNum).getImm();
679 O << ARM_ISB::InstSyncBOptToString(val);
674680 }
675681
676682 void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum,
7070 void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum,
7171 raw_ostream &O);
7272 void printMemBOption(const MCInst *MI, unsigned OpNum, raw_ostream &O);
73 void printInstSyncBOption(const MCInst *MI, unsigned OpNum, raw_ostream &O);
7374 void printShiftImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
7475 void printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, raw_ostream &O);
7576 void printPKHASRShiftImm(const MCInst *MI, unsigned OpNum, raw_ostream &O);
160160 }
161161 } // namespace ARM_MB
162162
163 namespace ARM_ISB {
164 enum InstSyncBOpt {
165 RESERVED_0 = 0,
166 RESERVED_1 = 1,
167 RESERVED_2 = 2,
168 RESERVED_3 = 3,
169 RESERVED_4 = 4,
170 RESERVED_5 = 5,
171 RESERVED_6 = 6,
172 RESERVED_7 = 7,
173 RESERVED_8 = 8,
174 RESERVED_9 = 9,
175 RESERVED_10 = 10,
176 RESERVED_11 = 11,
177 RESERVED_12 = 12,
178 RESERVED_13 = 13,
179 RESERVED_14 = 14,
180 SY = 15
181 };
182
183 inline static const char *InstSyncBOptToString(unsigned val) {
184 switch (val) {
185 default: llvm_unreachable("Unkown memory operation");
186 case RESERVED_0: return "#0x0";
187 case RESERVED_1: return "#0x1";
188 case RESERVED_2: return "#0x2";
189 case RESERVED_3: return "#0x3";
190 case RESERVED_4: return "#0x4";
191 case RESERVED_5: return "#0x5";
192 case RESERVED_6: return "#0x6";
193 case RESERVED_7: return "#0x7";
194 case RESERVED_8: return "#0x8";
195 case RESERVED_9: return "#0x9";
196 case RESERVED_10: return "#0xa";
197 case RESERVED_11: return "#0xb";
198 case RESERVED_12: return "#0xc";
199 case RESERVED_13: return "#0xd";
200 case RESERVED_14: return "#0xe";
201 case SY: return "sy";
202 }
203 }
204 } // namespace ARM_ISB
205
163206 /// isARMLowRegister - Returns true if the register is a low register (r0-r7).
164207 ///
165208 static inline bool isARMLowRegister(unsigned Reg) {
777777 @------------------------------------------------------------------------------
778778 isb sy
779779 isb
780 isb #15
781 isb #1
780782
781783 @ CHECK: isb sy @ encoding: [0x6f,0xf0,0x7f,0xf5]
782784 @ CHECK: isb sy @ encoding: [0x6f,0xf0,0x7f,0xf5]
785 @ CHECK: isb sy @ encoding: [0x6f,0xf0,0x7f,0xf5]
786 @ CHECK: isb #0x1 @ encoding: [0x61,0xf0,0x7f,0xf5]
783787
784788
785789 @------------------------------------------------------------------------------
570570 @------------------------------------------------------------------------------
571571 isb sy
572572 isb
573 isb #15
574 isb #1
573575
574576 @ CHECK: isb sy @ encoding: [0xbf,0xf3,0x6f,0x8f]
575577 @ CHECK: isb sy @ encoding: [0xbf,0xf3,0x6f,0x8f]
578 @ CHECK: isb sy @ encoding: [0xbf,0xf3,0x6f,0x8f]
579 @ CHECK: isb #0x1 @ encoding: [0xbf,0xf3,0x61,0x8f]
576580
577581
578582 @------------------------------------------------------------------------------
370370 @ CHECK-ERRORS: error: invalid operand for instruction
371371 @ CHECK-ERRORS: msr foo, #0
372372 @ CHECK-ERRORS: ^
373
374 isb #-1
375 isb #16
376 @ CHECK-ERRORS: error: immediate value out of range
377 @ CHECK-ERRORS: error: immediate value out of range
4141 @ CHECK-ERRORS: error: invalid operand for instruction
4242 @ CHECK-ERRORS: error: immediate operand must be in the range [0,15]
4343 @ CHECK-ERRORS: error: immediate operand must be in the range [0,15]
44
45 isb #-1
46 isb #16
47 @ CHECK-ERRORS: error: immediate value out of range
48 @ CHECK-ERRORS: error: immediate value out of range
612612 # ISB
613613 #------------------------------------------------------------------------------
614614 # CHECK: isb sy
615 # CHECK: isb #0xa
615616
616617 0x6f 0xf0 0x7f 0xf5
618 0x6a 0xf0 0x7f 0xf5
617619
618620
619621
446446 # ISB
447447 #------------------------------------------------------------------------------
448448 #CHECK: isb sy
449 #CHECK: isb #0xa
449450
450451 0xbf 0xf3 0x6f 0x8f
452 0xbf 0xf3 0x6a 0x8f
451453
452454 #------------------------------------------------------------------------------
453455 # IT