diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 14 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb2.td | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 16 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h | 2 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/basic-arm-instructions.s | 11 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/diagnostics.s | 11 | ||||
| -rw-r--r-- | llvm/utils/TableGen/EDEmitter.cpp | 1 | 
8 files changed, 55 insertions, 6 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 6e9743ffad5..83a25148040 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -543,10 +543,20 @@ def imm1_32_XFORM: SDNodeXForm<imm, [{  def Imm1_32AsmOperand: AsmOperandClass { let Name = "Imm1_32"; }  def imm1_32 : Operand<i32>, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 32; }],      imm1_32_XFORM> { -  let PrintMethod = "printImm1_32Operand"; +  let PrintMethod = "printImmPlusOneOperand";    let ParserMatchClass = Imm1_32AsmOperand;  } +def imm1_16_XFORM: SDNodeXForm<imm, [{ +  return CurDAG->getTargetConstant((int)N->getZExtValue() - 1, MVT::i32); +}]>; +def Imm1_16AsmOperand: AsmOperandClass { let Name = "Imm1_16"; } +def imm1_16 : Operand<i32>, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 16; }], +    imm1_16_XFORM> { +  let PrintMethod = "printImmPlusOneOperand"; +  let ParserMatchClass = Imm1_16AsmOperand; +} +  // Define ARM specific addressing modes.  // addrmode_imm12 := reg +/- imm12  // @@ -2709,7 +2719,7 @@ def SSAT : AI<(outs GPR:$Rd), (ins imm1_32:$sat_imm, GPR:$Rn, shift_imm:$sh),    let Inst{3-0} = Rn;  } -def SSAT16 : AI<(outs GPR:$Rd), (ins imm1_32:$sat_imm, GPR:$Rn), SatFrm, +def SSAT16 : AI<(outs GPR:$Rd), (ins imm1_16:$sat_imm, GPR:$Rn), SatFrm,                  NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []> {    bits<4> Rd;    bits<4> sat_imm; diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index 808ae51a600..1a9ab1c8763 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -1935,7 +1935,7 @@ def t2SSAT: T2SatI<  }  def t2SSAT16: T2SatI< -                (outs rGPR:$Rd), (ins imm1_32:$sat_imm, rGPR:$Rn), NoItinerary, +                (outs rGPR:$Rd), (ins imm1_16:$sat_imm, rGPR:$Rn), NoItinerary,                  "ssat16", "\t$Rd, $sat_imm, $Rn",                  [/* For disassembly only; pattern left blank */]>,            Requires<[IsThumb2, HasThumb2DSP]> { diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 02ed5477d4f..f6f8adc666c 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -433,6 +433,14 @@ public:      int64_t Value = CE->getValue();      return Value >= 0 && Value < 32;    } +  bool isImm1_16() const { +    if (Kind != Immediate) +      return false; +    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); +    if (!CE) return false; +    int64_t Value = CE->getValue(); +    return Value > 0 && Value < 17; +  }    bool isImm1_32() const {      if (Kind != Immediate)        return false; @@ -704,6 +712,14 @@ public:      addExpr(Inst, getImm());    } +  void addImm1_16Operands(MCInst &Inst, unsigned N) const { +    assert(N == 1 && "Invalid number of operands!"); +    // The constant encodes as the immediate-1, and we store in the instruction +    // the bits as encoded, so subtract off one here. +    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); +    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); +  } +    void addImm1_32Operands(MCInst &Inst, unsigned N) const {      assert(N == 1 && "Invalid number of operands!");      // The constant encodes as the immediate-1, and we store in the instruction diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index 296080a8174..3e58631c6ce 100644 --- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -830,8 +830,8 @@ void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,    O << "#0x" << utohexstr(Val);  } -void ARMInstPrinter::printImm1_32Operand(const MCInst *MI, unsigned OpNum, -                                         raw_ostream &O) { +void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, +                                            raw_ostream &O) {    unsigned Imm = MI->getOperand(OpNum).getImm();    O << "#" << Imm + 1;  } diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h index 208a3a71f14..c254ace6bc6 100644 --- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h +++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h @@ -114,7 +114,7 @@ public:    void printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);    void printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);    void printNEONModImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); -  void printImm1_32Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); +  void printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);    void printPCLabel(const MCInst *MI, unsigned OpNum, raw_ostream &O);  }; diff --git a/llvm/test/MC/ARM/basic-arm-instructions.s b/llvm/test/MC/ARM/basic-arm-instructions.s index 0439e70c441..b00b70b7b4d 100644 --- a/llvm/test/MC/ARM/basic-arm-instructions.s +++ b/llvm/test/MC/ARM/basic-arm-instructions.s @@ -1631,6 +1631,17 @@ _func:  @ CHECK: ssat	r8, #1, r10, asr #32    @ encoding: [0x5a,0x80,0xa0,0xe6]  @ CHECK: ssat	r8, #1, r10, asr #1     @ encoding: [0xda,0x80,0xa0,0xe6] + +@------------------------------------------------------------------------------ +@ SSAT16 +@------------------------------------------------------------------------------ +	ssat16	r2, #1, r7 +	ssat16	r3, #16, r5 + +@ CHECK: ssat16	r2, #1, r7              @ encoding: [0x37,0x2f,0xa0,0xe6] +@ CHECK: ssat16	r3, #16, r5             @ encoding: [0x35,0x3f,0xaf,0xe6] + +  @------------------------------------------------------------------------------  @ STM*  @------------------------------------------------------------------------------ diff --git a/llvm/test/MC/ARM/diagnostics.s b/llvm/test/MC/ARM/diagnostics.s index a8b2d9d4faa..aff242cc0be 100644 --- a/llvm/test/MC/ARM/diagnostics.s +++ b/llvm/test/MC/ARM/diagnostics.s @@ -200,3 +200,14 @@  @ CHECK: error: shift amount must be an immediate  @ CHECK:         ssat    r8, #1, r10, lsl #fred  @ CHECK:                                   ^ + +        @ Out of range immediates for SSAT16 +	ssat16	r2, #0, r7 +	ssat16	r3, #17, r5 + +@ CHECK: error: invalid operand for instruction +@ CHECK: 	ssat16	r2, #0, r7 +@ CHECK: 	      	    ^ +@ CHECK: error: invalid operand for instruction +@ CHECK: 	ssat16	r3, #17, r5 +@ CHECK: 	      	    ^ diff --git a/llvm/utils/TableGen/EDEmitter.cpp b/llvm/utils/TableGen/EDEmitter.cpp index 3001192e7f8..c9542cb8e75 100644 --- a/llvm/utils/TableGen/EDEmitter.cpp +++ b/llvm/utils/TableGen/EDEmitter.cpp @@ -587,6 +587,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,    IMM("neg_zero");    IMM("imm0_31");    IMM("imm0_31_m1"); +  IMM("imm1_16");    IMM("imm1_32");    IMM("nModImm");    IMM("imm0_7");  | 

