Skip to content

Commit 1179470

Browse files
author
Sjoerd Meijer
committedApr 3, 2017
ARMAsmParser: clean up of isImmediate functions
- we are now using immediate AsmOperands so that the range check functions are tablegen'ed. - Big bonus is that error messages become much more accurate, i.e. instead of a useless "invalid operand" error message it will not say that the immediate operand must in range [x,y], which is why regression tests needed updating. More tablegen operand descriptions could probably benefit from using immediateAsmOperand, but this is a first good step to get rid of most of the nearly identical range check functions. I will address the remaining immediate operands in next clean ups. Differential Revision: https://reviews.llvm.org/D31333 llvm-svn: 299358
1 parent 0b8949e commit 1179470

14 files changed

+193
-282
lines changed
 

‎llvm/lib/Target/ARM/ARMInstrFormats.td

+6-6
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> {
184184

185185
// ARM special operands for disassembly only.
186186
//
187-
def SetEndAsmOperand : ImmAsmOperand {
187+
def SetEndAsmOperand : ImmAsmOperand<0,1> {
188188
let Name = "SetEndImm";
189189
let ParserMethod = "parseSetEndImm";
190190
}
@@ -221,25 +221,25 @@ def banked_reg : Operand<i32> {
221221
// 16 imm6<5:4> = '01', 16 - <imm> is encoded in imm6<3:0>
222222
// 32 imm6<5> = '1', 32 - <imm> is encoded in imm6<4:0>
223223
// 64 64 - <imm> is encoded in imm6<5:0>
224-
def shr_imm8_asm_operand : ImmAsmOperand { let Name = "ShrImm8"; }
224+
def shr_imm8_asm_operand : ImmAsmOperand<1,8> { let Name = "ShrImm8"; }
225225
def shr_imm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 8; }]> {
226226
let EncoderMethod = "getShiftRight8Imm";
227227
let DecoderMethod = "DecodeShiftRight8Imm";
228228
let ParserMatchClass = shr_imm8_asm_operand;
229229
}
230-
def shr_imm16_asm_operand : ImmAsmOperand { let Name = "ShrImm16"; }
230+
def shr_imm16_asm_operand : ImmAsmOperand<1,16> { let Name = "ShrImm16"; }
231231
def shr_imm16 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 16; }]> {
232232
let EncoderMethod = "getShiftRight16Imm";
233233
let DecoderMethod = "DecodeShiftRight16Imm";
234234
let ParserMatchClass = shr_imm16_asm_operand;
235235
}
236-
def shr_imm32_asm_operand : ImmAsmOperand { let Name = "ShrImm32"; }
236+
def shr_imm32_asm_operand : ImmAsmOperand<1,32> { let Name = "ShrImm32"; }
237237
def shr_imm32 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]> {
238238
let EncoderMethod = "getShiftRight32Imm";
239239
let DecoderMethod = "DecodeShiftRight32Imm";
240240
let ParserMatchClass = shr_imm32_asm_operand;
241241
}
242-
def shr_imm64_asm_operand : ImmAsmOperand { let Name = "ShrImm64"; }
242+
def shr_imm64_asm_operand : ImmAsmOperand<1,64> { let Name = "ShrImm64"; }
243243
def shr_imm64 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 64; }]> {
244244
let EncoderMethod = "getShiftRight64Imm";
245245
let DecoderMethod = "DecodeShiftRight64Imm";
@@ -957,7 +957,7 @@ class ADivA1I<bits<3> opcod, dag oops, dag iops,
957957
}
958958

959959
// PKH instructions
960-
def PKHLSLAsmOperand : ImmAsmOperand {
960+
def PKHLSLAsmOperand : ImmAsmOperand<0,31> {
961961
let Name = "PKHLSLImm";
962962
let ParserMethod = "parsePKHLSLImm";
963963
}

‎llvm/lib/Target/ARM/ARMInstrInfo.td

+49-24
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,16 @@ def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{
441441
//
442442

443443
// Immediate operands with a shared generic asm render method.
444-
class ImmAsmOperand : AsmOperandClass { let RenderMethod = "addImmOperands"; }
444+
class ImmAsmOperand<int Low, int High> : AsmOperandClass {
445+
let RenderMethod = "addImmOperands";
446+
let PredicateMethod = "isImmediate<" # Low # "," # High # ">";
447+
let DiagnosticType = "ImmRange" # Low # "_" # High;
448+
}
449+
450+
class ImmAsmOperandMinusOne<int Low, int High> : AsmOperandClass {
451+
let PredicateMethod = "isImmediate<" # Low # "," # High # ">";
452+
let DiagnosticType = "ImmRange" # Low # "_" # High;
453+
}
445454

446455
// Operands that are part of a memory addressing mode.
447456
class MemOperand : Operand<i32> { let OperandType = "OPERAND_MEMORY"; }
@@ -663,61 +672,71 @@ def arm_i32imm : PatLeaf<(imm), [{
663672
}]>;
664673

665674
/// imm0_1 predicate - Immediate in the range [0,1].
666-
def Imm0_1AsmOperand: ImmAsmOperand { let Name = "Imm0_1"; }
675+
def Imm0_1AsmOperand: ImmAsmOperand<0,1> { let Name = "Imm0_1"; }
667676
def imm0_1 : Operand<i32> { let ParserMatchClass = Imm0_1AsmOperand; }
668677

669678
/// imm0_3 predicate - Immediate in the range [0,3].
670-
def Imm0_3AsmOperand: ImmAsmOperand { let Name = "Imm0_3"; }
679+
def Imm0_3AsmOperand: ImmAsmOperand<0,3> { let Name = "Imm0_3"; }
671680
def imm0_3 : Operand<i32> { let ParserMatchClass = Imm0_3AsmOperand; }
672681

673682
/// imm0_7 predicate - Immediate in the range [0,7].
674-
def Imm0_7AsmOperand: ImmAsmOperand { let Name = "Imm0_7"; }
683+
def Imm0_7AsmOperand: ImmAsmOperand<0,7> {
684+
let Name = "Imm0_7";
685+
}
675686
def imm0_7 : Operand<i32>, ImmLeaf<i32, [{
676687
return Imm >= 0 && Imm < 8;
677688
}]> {
678689
let ParserMatchClass = Imm0_7AsmOperand;
679690
}
680691

692+
/// imm8_255 predicate - Immediate in the range [8,255].
693+
def Imm8_255AsmOperand: ImmAsmOperand<8,255> { let Name = "Imm8_255"; }
694+
def imm8_255 : Operand<i32>, ImmLeaf<i32, [{
695+
return Imm >= 8 && Imm < 256;
696+
}]> {
697+
let ParserMatchClass = Imm8_255AsmOperand;
698+
}
699+
681700
/// imm8 predicate - Immediate is exactly 8.
682-
def Imm8AsmOperand: ImmAsmOperand { let Name = "Imm8"; }
701+
def Imm8AsmOperand: ImmAsmOperand<8,8> { let Name = "Imm8"; }
683702
def imm8 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 8; }]> {
684703
let ParserMatchClass = Imm8AsmOperand;
685704
}
686705

687706
/// imm16 predicate - Immediate is exactly 16.
688-
def Imm16AsmOperand: ImmAsmOperand { let Name = "Imm16"; }
707+
def Imm16AsmOperand: ImmAsmOperand<16,16> { let Name = "Imm16"; }
689708
def imm16 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 16; }]> {
690709
let ParserMatchClass = Imm16AsmOperand;
691710
}
692711

693712
/// imm32 predicate - Immediate is exactly 32.
694-
def Imm32AsmOperand: ImmAsmOperand { let Name = "Imm32"; }
713+
def Imm32AsmOperand: ImmAsmOperand<32,32> { let Name = "Imm32"; }
695714
def imm32 : Operand<i32>, ImmLeaf<i32, [{ return Imm == 32; }]> {
696715
let ParserMatchClass = Imm32AsmOperand;
697716
}
698717

699718
def imm8_or_16 : ImmLeaf<i32, [{ return Imm == 8 || Imm == 16;}]>;
700719

701720
/// imm1_7 predicate - Immediate in the range [1,7].
702-
def Imm1_7AsmOperand: ImmAsmOperand { let Name = "Imm1_7"; }
721+
def Imm1_7AsmOperand: ImmAsmOperand<1,7> { let Name = "Imm1_7"; }
703722
def imm1_7 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 8; }]> {
704723
let ParserMatchClass = Imm1_7AsmOperand;
705724
}
706725

707726
/// imm1_15 predicate - Immediate in the range [1,15].
708-
def Imm1_15AsmOperand: ImmAsmOperand { let Name = "Imm1_15"; }
727+
def Imm1_15AsmOperand: ImmAsmOperand<1,15> { let Name = "Imm1_15"; }
709728
def imm1_15 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 16; }]> {
710729
let ParserMatchClass = Imm1_15AsmOperand;
711730
}
712731

713732
/// imm1_31 predicate - Immediate in the range [1,31].
714-
def Imm1_31AsmOperand: ImmAsmOperand { let Name = "Imm1_31"; }
733+
def Imm1_31AsmOperand: ImmAsmOperand<1,31> { let Name = "Imm1_31"; }
715734
def imm1_31 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 32; }]> {
716735
let ParserMatchClass = Imm1_31AsmOperand;
717736
}
718737

719738
/// imm0_15 predicate - Immediate in the range [0,15].
720-
def Imm0_15AsmOperand: ImmAsmOperand {
739+
def Imm0_15AsmOperand: ImmAsmOperand<0,15> {
721740
let Name = "Imm0_15";
722741
let DiagnosticType = "ImmRange0_15";
723742
}
@@ -728,31 +747,31 @@ def imm0_15 : Operand<i32>, ImmLeaf<i32, [{
728747
}
729748

730749
/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31].
731-
def Imm0_31AsmOperand: ImmAsmOperand { let Name = "Imm0_31"; }
750+
def Imm0_31AsmOperand: ImmAsmOperand<0,31> { let Name = "Imm0_31"; }
732751
def imm0_31 : Operand<i32>, ImmLeaf<i32, [{
733752
return Imm >= 0 && Imm < 32;
734753
}]> {
735754
let ParserMatchClass = Imm0_31AsmOperand;
736755
}
737756

738757
/// imm0_32 predicate - True if the 32-bit immediate is in the range [0,32].
739-
def Imm0_32AsmOperand: ImmAsmOperand { let Name = "Imm0_32"; }
758+
def Imm0_32AsmOperand: ImmAsmOperand<0,32> { let Name = "Imm0_32"; }
740759
def imm0_32 : Operand<i32>, ImmLeaf<i32, [{
741-
return Imm >= 0 && Imm < 32;
760+
return Imm >= 0 && Imm < 33;
742761
}]> {
743762
let ParserMatchClass = Imm0_32AsmOperand;
744763
}
745764

746765
/// imm0_63 predicate - True if the 32-bit immediate is in the range [0,63].
747-
def Imm0_63AsmOperand: ImmAsmOperand { let Name = "Imm0_63"; }
766+
def Imm0_63AsmOperand: ImmAsmOperand<0,63> { let Name = "Imm0_63"; }
748767
def imm0_63 : Operand<i32>, ImmLeaf<i32, [{
749768
return Imm >= 0 && Imm < 64;
750769
}]> {
751770
let ParserMatchClass = Imm0_63AsmOperand;
752771
}
753772

754773
/// imm0_239 predicate - Immediate in the range [0,239].
755-
def Imm0_239AsmOperand : ImmAsmOperand {
774+
def Imm0_239AsmOperand : ImmAsmOperand<0,239> {
756775
let Name = "Imm0_239";
757776
let DiagnosticType = "ImmRange0_239";
758777
}
@@ -761,13 +780,13 @@ def imm0_239 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 240; }]> {
761780
}
762781

763782
/// imm0_255 predicate - Immediate in the range [0,255].
764-
def Imm0_255AsmOperand : ImmAsmOperand { let Name = "Imm0_255"; }
783+
def Imm0_255AsmOperand : ImmAsmOperand<0,255> { let Name = "Imm0_255"; }
765784
def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> {
766785
let ParserMatchClass = Imm0_255AsmOperand;
767786
}
768787

769-
/// imm0_65535 - An immediate is in the range [0.65535].
770-
def Imm0_65535AsmOperand: ImmAsmOperand { let Name = "Imm0_65535"; }
788+
/// imm0_65535 - An immediate is in the range [0,65535].
789+
def Imm0_65535AsmOperand: ImmAsmOperand<0,65535> { let Name = "Imm0_65535"; }
771790
def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
772791
return Imm >= 0 && Imm < 65536;
773792
}]> {
@@ -785,19 +804,23 @@ def imm0_65535_neg : Operand<i32>, ImmLeaf<i32, [{
785804
// FIXME: This really needs a Thumb version separate from the ARM version.
786805
// While the range is the same, and can thus use the same match class,
787806
// the encoding is different so it should have a different encoder method.
788-
def Imm0_65535ExprAsmOperand: ImmAsmOperand { let Name = "Imm0_65535Expr"; }
807+
def Imm0_65535ExprAsmOperand: AsmOperandClass {
808+
let Name = "Imm0_65535Expr";
809+
let RenderMethod = "addImmOperands";
810+
}
811+
789812
def imm0_65535_expr : Operand<i32> {
790813
let EncoderMethod = "getHiLo16ImmOpValue";
791814
let ParserMatchClass = Imm0_65535ExprAsmOperand;
792815
}
793816

794-
def Imm256_65535ExprAsmOperand: ImmAsmOperand { let Name = "Imm256_65535Expr"; }
817+
def Imm256_65535ExprAsmOperand: ImmAsmOperand<256,65535> { let Name = "Imm256_65535Expr"; }
795818
def imm256_65535_expr : Operand<i32> {
796819
let ParserMatchClass = Imm256_65535ExprAsmOperand;
797820
}
798821

799822
/// imm24b - True if the 32-bit immediate is encodable in 24 bits.
800-
def Imm24bitAsmOperand: ImmAsmOperand { let Name = "Imm24bit"; }
823+
def Imm24bitAsmOperand: ImmAsmOperand<0,0xffffff> { let Name = "Imm24bit"; }
801824
def imm24b : Operand<i32>, ImmLeaf<i32, [{
802825
return Imm >= 0 && Imm <= 0xffffff;
803826
}]> {
@@ -826,7 +849,9 @@ def imm1_32_XFORM: SDNodeXForm<imm, [{
826849
return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, SDLoc(N),
827850
MVT::i32);
828851
}]>;
829-
def Imm1_32AsmOperand: AsmOperandClass { let Name = "Imm1_32"; }
852+
def Imm1_32AsmOperand: ImmAsmOperandMinusOne<1,32> {
853+
let Name = "Imm1_32";
854+
}
830855
def imm1_32 : Operand<i32>, PatLeaf<(imm), [{
831856
uint64_t Imm = N->getZExtValue();
832857
return Imm > 0 && Imm <= 32;
@@ -840,7 +865,7 @@ def imm1_16_XFORM: SDNodeXForm<imm, [{
840865
return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, SDLoc(N),
841866
MVT::i32);
842867
}]>;
843-
def Imm1_16AsmOperand: AsmOperandClass { let Name = "Imm1_16"; }
868+
def Imm1_16AsmOperand: ImmAsmOperandMinusOne<1,16> { let Name = "Imm1_16"; }
844869
def imm1_16 : Operand<i32>, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 16; }],
845870
imm1_16_XFORM> {
846871
let PrintMethod = "printImmPlusOneOperand";

‎llvm/lib/Target/ARM/ARMInstrThumb.td

+1-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def imm_sr_XFORM: SDNodeXForm<imm, [{
1919
unsigned Imm = N->getZExtValue();
2020
return CurDAG->getTargetConstant((Imm == 32 ? 0 : Imm), SDLoc(N), MVT::i32);
2121
}]>;
22-
def ThumbSRImmAsmOperand: AsmOperandClass { let Name = "ImmThumbSR"; }
22+
def ThumbSRImmAsmOperand: ImmAsmOperand<1,32> { let Name = "ImmThumbSR"; }
2323
def imm_sr : Operand<i32>, PatLeaf<(imm), [{
2424
uint64_t Imm = N->getZExtValue();
2525
return Imm > 0 && Imm <= 32;
@@ -53,9 +53,6 @@ def imm0_255_comp : PatLeaf<(i32 imm), [{
5353
return ~((uint32_t)N->getZExtValue()) < 256;
5454
}]>;
5555

56-
def imm8_255 : ImmLeaf<i32, [{
57-
return Imm >= 8 && Imm < 256;
58-
}]>;
5956
def imm8_255_neg : PatLeaf<(i32 imm), [{
6057
unsigned Val = -N->getZExtValue();
6158
return Val >= 8 && Val < 256;

‎llvm/lib/Target/ARM/ARMInstrThumb2.td

+7-3
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ def t2_so_imm_notSext16_XFORM : SDNodeXForm<imm, [{
7676
// t2_so_imm - Match a 32-bit immediate operand, which is an
7777
// 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit
7878
// immediate splatted into multiple bytes of the word.
79-
def t2_so_imm_asmoperand : ImmAsmOperand { let Name = "T2SOImm"; }
79+
def t2_so_imm_asmoperand : AsmOperandClass {
80+
let Name = "T2SOImm";
81+
let RenderMethod = "addImmOperands";
82+
83+
}
8084
def t2_so_imm : Operand<i32>, ImmLeaf<i32, [{
8185
return ARM_AM::getT2SOImmVal(Imm) != -1;
8286
}]> {
@@ -116,8 +120,8 @@ def t2_so_imm_neg : Operand<i32>, ImmLeaf<i32, [{
116120
let ParserMatchClass = t2_so_imm_neg_asmoperand;
117121
}
118122

119-
/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
120-
def imm0_4095_asmoperand: ImmAsmOperand { let Name = "Imm0_4095"; }
123+
/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0,4095].
124+
def imm0_4095_asmoperand: ImmAsmOperand<0,4095> { let Name = "Imm0_4095"; }
121125
def imm0_4095 : Operand<i32>, ImmLeaf<i32, [{
122126
return Imm >= 0 && Imm < 4096;
123127
}]> {

0 commit comments

Comments
 (0)
Please sign in to comment.