From: Jim Grosbach Date: Mon, 25 Jul 2011 23:09:14 +0000 (+0000) Subject: ARM assembly parsing and encoding for SSAT16 instruction. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=f49433523e8a39db6d83503e312ae55160eed90a;p=oota-llvm.git ARM assembly parsing and encoding for SSAT16 instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136006 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 6e9743ffad5..83a25148040 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -543,10 +543,20 @@ def imm1_32_XFORM: SDNodeXForm, 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: SDNodeXFormgetTargetConstant((int)N->getZExtValue() - 1, MVT::i32); +}]>; +def Imm1_16AsmOperand: AsmOperandClass { let Name = "Imm1_16"; } +def imm1_16 : Operand, 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/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 808ae51a600..1a9ab1c8763 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/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/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 02ed5477d4f..f6f8adc666c 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/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(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(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/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index 296080a8174..3e58631c6ce 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/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/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h index 208a3a71f14..c254ace6bc6 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h +++ b/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/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s index 0439e70c441..b00b70b7b4d 100644 --- a/test/MC/ARM/basic-arm-instructions.s +++ b/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/test/MC/ARM/diagnostics.s b/test/MC/ARM/diagnostics.s index a8b2d9d4faa..aff242cc0be 100644 --- a/test/MC/ARM/diagnostics.s +++ b/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/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 3001192e7f8..c9542cb8e75 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/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");