diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 8397e3bf1d7..16d4ca599a0 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -232,6 +232,8 @@ namespace { unsigned Op) const { return 0; } unsigned getMsbOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getSsatBitPosValue(const MachineInstr &MI, + unsigned Op) const { return 0; } uint32_t getLdStmModeOpValue(const MachineInstr &MI, unsigned OpIdx) const {return 0; } uint32_t getLdStSORegOpValue(const MachineInstr &MI, unsigned OpIdx) diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index fd550219fe2..f6ccf75ba77 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -475,6 +475,12 @@ def width_imm : Operand, ImmLeaf, ImmLeaf 0 && Imm <= 32; +}]> { + let EncoderMethod = "getSsatBitPosValue"; +} + // Define ARM specific addressing modes. def MemMode2AsmOperand : AsmOperandClass { @@ -2455,7 +2461,7 @@ def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), // Signed/Unsigned saturate -- for disassembly only -def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh), +def SSAT : AI<(outs GPR:$Rd), (ins ssat_imm:$sat_imm, GPR:$a, shift_imm:$sh), SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh", [/* For disassembly only; pattern left blank */]> { bits<4> Rd; @@ -2471,7 +2477,7 @@ def SSAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh), let Inst{3-0} = Rn; } -def SSAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$Rn), SatFrm, +def SSAT16 : AI<(outs GPR:$Rd), (ins ssat_imm:$sat_imm, GPR:$Rn), SatFrm, NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", [/* For disassembly only; pattern left blank */]> { bits<4> Rd; diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index e86f2767cad..5b8124fd1ea 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -1973,9 +1973,9 @@ class T2SatI { + (outs rGPR:$Rd), (ins ssat_imm:$sat_imm, rGPR:$Rn, shift_imm:$sh), + NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", + [/* For disassembly only; pattern left blank */]> { let Inst{31-27} = 0b11110; let Inst{25-22} = 0b1100; let Inst{20} = 0; @@ -1983,9 +1983,9 @@ def t2SSAT: T2SatI< } def t2SSAT16: T2SatI< - (outs rGPR:$Rd), (ins i32imm:$sat_imm, rGPR:$Rn), NoItinerary, - "ssat16", "\t$Rd, $sat_imm, $Rn", - [/* For disassembly only; pattern left blank */]> { + (outs rGPR:$Rd), (ins ssat_imm:$sat_imm, rGPR:$Rn), NoItinerary, + "ssat16", "\t$Rd, $sat_imm, $Rn", + [/* For disassembly only; pattern left blank */]> { let Inst{31-27} = 0b11110; let Inst{25-22} = 0b1100; let Inst{20} = 0; diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index 2b6d9fcfb33..c5f727d6064 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -269,6 +269,9 @@ public: unsigned getMsbOpValue(const MCInst &MI, unsigned Op, SmallVectorImpl &Fixups) const; + unsigned getSsatBitPosValue(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups) const; + unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op, SmallVectorImpl &Fixups) const; unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op, @@ -1123,6 +1126,13 @@ getMsbOpValue(const MCInst &MI, unsigned Op, return msb; } +unsigned ARMMCCodeEmitter:: +getSsatBitPosValue(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups) const { + // For ssat instructions, the bit position should be encoded decremented by 1 + return MI.getOperand(Op).getImm()-1; +} + unsigned ARMMCCodeEmitter:: getRegisterListOpValue(const MCInst &MI, unsigned Op, SmallVectorImpl &Fixups) const { diff --git a/test/MC/ARM/arm_instructions.s b/test/MC/ARM/arm_instructions.s index a231e414412..f7894411ec5 100644 --- a/test/MC/ARM/arm_instructions.s +++ b/test/MC/ARM/arm_instructions.s @@ -312,3 +312,6 @@ @ CHECK: ldrexd r0, r1, [r0] @ encoding: [0x9f,0x0f,0xb0,0xe1] ldrexd r0, r1, [r0] +@ CHECK: ssat16 r0, #7, r0 @ encoding: [0x30,0x0f,0xa6,0xe6] + ssat16 r0, #7, r0 + diff --git a/test/MC/ARM/thumb2.s b/test/MC/ARM/thumb2.s index 5342b9001e4..4e9d4e18597 100644 --- a/test/MC/ARM/thumb2.s +++ b/test/MC/ARM/thumb2.s @@ -300,3 +300,5 @@ ldrex r0, [r0] @ CHECK: ldrexd r0, r1, [r0] @ encoding: [0xd0,0xe8,0x7f,0x01] ldrexd r0, r1, [r0] +@ CHECK: ssat16 r0, #7, r0 @ encoding: [0x20,0xf3,0x06,0x00] + ssat16 r0, #7, r0 diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index cb0e5126a0f..daf96175545 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -596,6 +596,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, IMM("t_adrlabel"); IMM("t2adrlabel"); IMM("shift_imm"); + IMM("ssat_imm"); IMM("neon_vcvt_imm32"); IMM("shr_imm8"); IMM("shr_imm16");