[mips] Add range checks and transformation to octeon instructions in AsmParser.

This patch adds range checks to the immediate operands of octeon
instructions in the AsmParser. Like gas, it applies the following
transformations if the immediate is to large:

bbit0 $8, 42, foo => bbit032 $8, 10, foo
bbit1 $8, 46, foo => bbit132 $8, 14, foo
cins $8, $31, 32, 31 => cins32 $8, $31, 0, 31
exts $7, $4, 54, 9 => exts32 $7, $4, 22, 9

Reviewed By: dsanders

Differential Revision: http://reviews.llvm.org/D7080


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227225 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Kai Nacke 2015-01-27 19:11:28 +00:00
parent ed9cdced00
commit 47b633d4a5
2 changed files with 90 additions and 0 deletions

View File

@ -382,6 +382,9 @@ public:
bool hasMips64r6() const { bool hasMips64r6() const {
return (STI.getFeatureBits() & Mips::FeatureMips64r6); return (STI.getFeatureBits() & Mips::FeatureMips64r6);
} }
bool hasCnMips() const {
return (STI.getFeatureBits() & Mips::FeatureCnMips);
}
bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); } bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); } bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); } bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
@ -1168,6 +1171,13 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
switch (Opcode) { switch (Opcode) {
default: default:
break; break;
case Mips::BBIT0:
case Mips::BBIT032:
case Mips::BBIT1:
case Mips::BBIT132:
assert(hasCnMips() && "instruction only valid for octeon cpus");
// Fall through
case Mips::BEQ: case Mips::BEQ:
case Mips::BNE: case Mips::BNE:
case Mips::BEQ_MM: case Mips::BEQ_MM:
@ -1230,6 +1240,74 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
"nop instruction"); "nop instruction");
} }
if (hasCnMips()) {
const unsigned Opcode = Inst.getOpcode();
MCOperand Opnd;
int Imm;
switch (Opcode) {
default:
break;
case Mips::BBIT0:
case Mips::BBIT032:
case Mips::BBIT1:
case Mips::BBIT132:
assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
// The offset is handled above
Opnd = Inst.getOperand(1);
if (!Opnd.isImm())
return Error(IDLoc, "expected immediate operand kind");
Imm = Opnd.getImm();
if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
Opcode == Mips::BBIT1 ? 63 : 31))
return Error(IDLoc, "immediate operand value out of range");
if (Imm > 31) {
Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
: Mips::BBIT132);
Inst.getOperand(1).setImm(Imm - 32);
}
break;
case Mips::CINS:
case Mips::CINS32:
case Mips::EXTS:
case Mips::EXTS32:
assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
// Check length
Opnd = Inst.getOperand(3);
if (!Opnd.isImm())
return Error(IDLoc, "expected immediate operand kind");
Imm = Opnd.getImm();
if (Imm < 0 || Imm > 31)
return Error(IDLoc, "immediate operand value out of range");
// Check position
Opnd = Inst.getOperand(2);
if (!Opnd.isImm())
return Error(IDLoc, "expected immediate operand kind");
Imm = Opnd.getImm();
if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
Opcode == Mips::EXTS ? 63 : 31))
return Error(IDLoc, "immediate operand value out of range");
if (Imm > 31) {
Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
Inst.getOperand(2).setImm(Imm - 32);
}
break;
case Mips::SEQi:
case Mips::SNEi:
assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
Opnd = Inst.getOperand(2);
if (!Opnd.isImm())
return Error(IDLoc, "expected immediate operand kind");
Imm = Opnd.getImm();
if (!isInt<10>(Imm))
return Error(IDLoc, "immediate operand value out of range");
break;
}
}
if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) { if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
// If this instruction has a delay slot and .set reorder is active, // If this instruction has a delay slot and .set reorder is active,
// emit a NOP after it. // emit a NOP after it.

View File

@ -5,12 +5,16 @@
# CHECK: baddu $2, $2, $3 # encoding: [0x70,0x43,0x10,0x28] # CHECK: baddu $2, $2, $3 # encoding: [0x70,0x43,0x10,0x28]
# CHECK: bbit0 $19, 22, foo # encoding: [0xca,0x76,A,A] # CHECK: bbit0 $19, 22, foo # encoding: [0xca,0x76,A,A]
# CHECK: bbit032 $fp, 11, foo # encoding: [0xdb,0xcb,A,A] # CHECK: bbit032 $fp, 11, foo # encoding: [0xdb,0xcb,A,A]
# CHECK: bbit032 $8, 10, foo # encoding: [0xd9,0x0a,A,A]
# CHECK: bbit1 $3, 31, foo # encoding: [0xe8,0x7f,A,A] # CHECK: bbit1 $3, 31, foo # encoding: [0xe8,0x7f,A,A]
# CHECK: bbit132 $24, 10, foo # encoding: [0xfb,0x0a,A,A] # CHECK: bbit132 $24, 10, foo # encoding: [0xfb,0x0a,A,A]
# CHECK: bbit132 $14, 14, foo # encoding: [0xf9,0xce,A,A]
# CHECK: cins $25, $10, 22, 2 # encoding: [0x71,0x59,0x15,0xb2] # CHECK: cins $25, $10, 22, 2 # encoding: [0x71,0x59,0x15,0xb2]
# CHECK: cins $9, $9, 17, 29 # encoding: [0x71,0x29,0xec,0x72] # CHECK: cins $9, $9, 17, 29 # encoding: [0x71,0x29,0xec,0x72]
# CHECK: cins32 $15, $2, 18, 8 # encoding: [0x70,0x4f,0x44,0xb3] # CHECK: cins32 $15, $2, 18, 8 # encoding: [0x70,0x4f,0x44,0xb3]
# CHECK: cins32 $22, $22, 9, 22 # encoding: [0x72,0xd6,0xb2,0x73] # CHECK: cins32 $22, $22, 9, 22 # encoding: [0x72,0xd6,0xb2,0x73]
# CHECK: cins32 $24, $ra, 0, 31 # encoding: [0x73,0xf8,0xf8,0x33]
# CHECK: cins32 $15, $15, 5, 5 # encoding: [0x71,0xef,0x29,0x73]
# CHECK: dmul $9, $6, $7 # encoding: [0x70,0xc7,0x48,0x03] # CHECK: dmul $9, $6, $7 # encoding: [0x70,0xc7,0x48,0x03]
# CHECK: dmul $19, $24, $25 # encoding: [0x73,0x19,0x98,0x03] # CHECK: dmul $19, $24, $25 # encoding: [0x73,0x19,0x98,0x03]
# CHECK: dmul $9, $9, $6 # encoding: [0x71,0x26,0x48,0x03] # CHECK: dmul $9, $9, $6 # encoding: [0x71,0x26,0x48,0x03]
@ -22,6 +26,8 @@
# CHECK: exts $15, $15, 17, 6 # encoding: [0x71,0xef,0x34,0x7a] # CHECK: exts $15, $15, 17, 6 # encoding: [0x71,0xef,0x34,0x7a]
# CHECK: exts32 $4, $13, 10, 8 # encoding: [0x71,0xa4,0x42,0xbb] # CHECK: exts32 $4, $13, 10, 8 # encoding: [0x71,0xa4,0x42,0xbb]
# CHECK: exts32 $15, $15, 11, 20 # encoding: [0x71,0xef,0xa2,0xfb] # CHECK: exts32 $15, $15, 11, 20 # encoding: [0x71,0xef,0xa2,0xfb]
# CHECK: exts32 $7, $4, 22, 9 # encoding: [0x70,0x87,0x4d,0xbb]
# CHECK: exts32 $25, $25, 5, 25 # encoding: [0x73,0x39,0xc9,0x7b]
# CHECK: mtm0 $15 # encoding: [0x71,0xe0,0x00,0x08] # CHECK: mtm0 $15 # encoding: [0x71,0xe0,0x00,0x08]
# CHECK: mtm1 $16 # encoding: [0x72,0x00,0x00,0x0c] # CHECK: mtm1 $16 # encoding: [0x72,0x00,0x00,0x0c]
# CHECK: mtm2 $17 # encoding: [0x72,0x20,0x00,0x0d] # CHECK: mtm2 $17 # encoding: [0x72,0x20,0x00,0x0d]
@ -56,12 +62,16 @@ foo:
baddu $2, $3 baddu $2, $3
bbit0 $19, 22, foo bbit0 $19, 22, foo
bbit032 $30, 11, foo bbit032 $30, 11, foo
bbit0 $8, 42, foo
bbit1 $3, 31, foo bbit1 $3, 31, foo
bbit132 $24, 10, foo bbit132 $24, 10, foo
bbit1 $14, 46, foo
cins $25, $10, 22, 2 cins $25, $10, 22, 2
cins $9, 17, 29 cins $9, 17, 29
cins32 $15, $2, 18, 8 cins32 $15, $2, 18, 8
cins32 $22, 9, 22 cins32 $22, 9, 22
cins $24, $31, 32, 31
cins $15, 37, 5
dmul $9, $6, $7 dmul $9, $6, $7
dmul $19, $24, $25 dmul $19, $24, $25
dmul $9, $6 dmul $9, $6
@ -73,6 +83,8 @@ foo:
exts $15, 17, 6 exts $15, 17, 6
exts32 $4, $13, 10, 8 exts32 $4, $13, 10, 8
exts32 $15, 11, 20 exts32 $15, 11, 20
exts $7, $4, 54, 9
exts $25, 37, 25
mtm0 $15 mtm0 $15
mtm1 $16 mtm1 $16
mtm2 $17 mtm2 $17