mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 20:29:53 +00:00
[PowerPC] Support asm parsing for bc[l][a][+-] mnemonics
PowerPC assembly code in the wild, so it seems, has things like this: bc+ 12, 28, .L9 This is a bit odd because the '+' here becomes part of the BO field, and the BO field is otherwise the first operand. Nevertheless, the ISA specification does clearly say that the +- hint syntax applies to all conditional-branch mnemonics (that test either CTR or a condition register, although not the forms which check both), both basic and extended, so this is supposed to be valid. This introduces some asm-parser-only definitions which take only the upper three bits from the specified BO value, and the lower two bits are implied by the +- suffix (via some associated aliases). Fixes PR23646. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280571 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0d65f1da0e
commit
f86e7eec65
@ -545,6 +545,7 @@ public:
|
||||
&& isUInt<5>(getImm())); }
|
||||
bool isCRBitMask() const { return Kind == Immediate && isUInt<8>(getImm()) &&
|
||||
isPowerOf2_32(getImm()); }
|
||||
bool isATBitsAsHint() const { return false; }
|
||||
bool isMem() const override { return false; }
|
||||
bool isReg() const override { return false; }
|
||||
|
||||
|
@ -258,6 +258,15 @@ void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
|
||||
printOperand(MI, OpNo+1, O);
|
||||
}
|
||||
|
||||
void PPCInstPrinter::printATBitsAsHint(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) {
|
||||
unsigned Code = MI->getOperand(OpNo).getImm();
|
||||
if (Code == 2)
|
||||
O << "-";
|
||||
else if (Code == 3)
|
||||
O << "+";
|
||||
}
|
||||
|
||||
void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) {
|
||||
unsigned int Value = MI->getOperand(OpNo).getImm();
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printPredicateOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O, const char *Modifier = nullptr);
|
||||
void printATBitsAsHint(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
|
||||
void printU1ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU2ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
|
@ -163,6 +163,22 @@ class BForm_3<bits<6> opcode, bit aa, bit lk,
|
||||
let Inst{31} = lk;
|
||||
}
|
||||
|
||||
class BForm_3_at<bits<6> opcode, bit aa, bit lk,
|
||||
dag OOL, dag IOL, string asmstr>
|
||||
: I<opcode, OOL, IOL, asmstr, IIC_BrB> {
|
||||
bits<5> BO;
|
||||
bits<2> at;
|
||||
bits<5> BI;
|
||||
bits<14> BD;
|
||||
|
||||
let Inst{6-8} = BO{4-2};
|
||||
let Inst{9-10} = at;
|
||||
let Inst{11-15} = BI;
|
||||
let Inst{16-29} = BD;
|
||||
let Inst{30} = aa;
|
||||
let Inst{31} = lk;
|
||||
}
|
||||
|
||||
class BForm_4<bits<6> opcode, bits<5> bo, bit aa, bit lk,
|
||||
dag OOL, dag IOL, string asmstr>
|
||||
: I<opcode, OOL, IOL, asmstr, IIC_BrB> {
|
||||
|
@ -478,6 +478,15 @@ def u2imm : Operand<i32> {
|
||||
let ParserMatchClass = PPCU2ImmAsmOperand;
|
||||
}
|
||||
|
||||
def PPCATBitsAsHintAsmOperand : AsmOperandClass {
|
||||
let Name = "ATBitsAsHint"; let PredicateMethod = "isATBitsAsHint";
|
||||
let RenderMethod = "addImmOperands"; // Irrelevant, predicate always fails.
|
||||
}
|
||||
def atimm : Operand<i32> {
|
||||
let PrintMethod = "printATBitsAsHint";
|
||||
let ParserMatchClass = PPCATBitsAsHintAsmOperand;
|
||||
}
|
||||
|
||||
def PPCU3ImmAsmOperand : AsmOperandClass {
|
||||
let Name = "U3Imm"; let PredicateMethod = "isU3Imm";
|
||||
let RenderMethod = "addImmOperands";
|
||||
@ -4134,6 +4143,16 @@ let PPC970_Unit = 7 in {
|
||||
def gBCA : BForm_3<16, 1, 0, (outs),
|
||||
(ins u5imm:$bo, crbitrc:$bi, abscondbrtarget:$dst),
|
||||
"bca $bo, $bi, $dst">;
|
||||
let isAsmParserOnly = 1 in {
|
||||
def gBCat : BForm_3_at<16, 0, 0, (outs),
|
||||
(ins u5imm:$bo, atimm:$at, crbitrc:$bi,
|
||||
condbrtarget:$dst),
|
||||
"bc$at $bo, $bi, $dst">;
|
||||
def gBCAat : BForm_3_at<16, 1, 0, (outs),
|
||||
(ins u5imm:$bo, atimm:$at, crbitrc:$bi,
|
||||
abscondbrtarget:$dst),
|
||||
"bca$at $bo, $bi, $dst">;
|
||||
} // isAsmParserOnly = 1
|
||||
}
|
||||
let Defs = [LR, CTR], Uses = [CTR, RM] in {
|
||||
def gBCL : BForm_3<16, 0, 1, (outs),
|
||||
@ -4142,6 +4161,16 @@ let PPC970_Unit = 7 in {
|
||||
def gBCLA : BForm_3<16, 1, 1, (outs),
|
||||
(ins u5imm:$bo, crbitrc:$bi, abscondbrtarget:$dst),
|
||||
"bcla $bo, $bi, $dst">;
|
||||
let isAsmParserOnly = 1 in {
|
||||
def gBCLat : BForm_3_at<16, 0, 1, (outs),
|
||||
(ins u5imm:$bo, atimm:$at, crbitrc:$bi,
|
||||
condbrtarget:$dst),
|
||||
"bcl$at $bo, $bi, $dst">;
|
||||
def gBCLAat : BForm_3_at<16, 1, 1, (outs),
|
||||
(ins u5imm:$bo, atimm:$at, crbitrc:$bi,
|
||||
abscondbrtarget:$dst),
|
||||
"bcla$at $bo, $bi, $dst">;
|
||||
} // // isAsmParserOnly = 1
|
||||
}
|
||||
let Defs = [CTR], Uses = [CTR, LR, RM] in
|
||||
def gBCLR : XLForm_2<19, 16, 0, (outs),
|
||||
@ -4160,6 +4189,20 @@ let PPC970_Unit = 7 in {
|
||||
(ins u5imm:$bo, crbitrc:$bi, i32imm:$bh),
|
||||
"bcctrl $bo, $bi, $bh", IIC_BrB, []>;
|
||||
}
|
||||
|
||||
multiclass BranchSimpleMnemonicAT<string pm, int at> {
|
||||
def : InstAlias<"bc"#pm#" $bo, $bi, $dst", (gBCat u5imm:$bo, at, crbitrc:$bi,
|
||||
condbrtarget:$dst)>;
|
||||
def : InstAlias<"bca"#pm#" $bo, $bi, $dst", (gBCAat u5imm:$bo, at, crbitrc:$bi,
|
||||
condbrtarget:$dst)>;
|
||||
def : InstAlias<"bcl"#pm#" $bo, $bi, $dst", (gBCLat u5imm:$bo, at, crbitrc:$bi,
|
||||
condbrtarget:$dst)>;
|
||||
def : InstAlias<"bcla"#pm#" $bo, $bi, $dst", (gBCLAat u5imm:$bo, at, crbitrc:$bi,
|
||||
condbrtarget:$dst)>;
|
||||
}
|
||||
defm : BranchSimpleMnemonicAT<"+", 3>;
|
||||
defm : BranchSimpleMnemonicAT<"-", 2>;
|
||||
|
||||
def : InstAlias<"bclr $bo, $bi", (gBCLR u5imm:$bo, crbitrc:$bi, 0)>;
|
||||
def : InstAlias<"bclrl $bo, $bi", (gBCLRL u5imm:$bo, crbitrc:$bi, 0)>;
|
||||
def : InstAlias<"bcctr $bo, $bi", (gBCCTR u5imm:$bo, crbitrc:$bi, 0)>;
|
||||
|
@ -48,6 +48,47 @@
|
||||
# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
|
||||
bcla 4, 10, target
|
||||
|
||||
# CHECK-BE: bc+ 12, 28, target # encoding: [0x41,0xfc,A,0bAAAAAA00]
|
||||
# CHECK-LE: bc+ 12, 28, target # encoding: [0bAAAAAA00,A,0xfc,0x41]
|
||||
# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
|
||||
# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
|
||||
bc+ 12, 28, target
|
||||
# CHECK-BE: bc- 12, 28, target # encoding: [0x41,0xdc,A,0bAAAAAA00]
|
||||
# CHECK-LE: bc- 12, 28, target # encoding: [0bAAAAAA00,A,0xdc,0x41]
|
||||
# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
|
||||
# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
|
||||
bc- 12, 28, target
|
||||
# CHECK-BE: bca+ 12, 28, target # encoding: [0x41,0xfc,A,0bAAAAAA10]
|
||||
# CHECK-LE: bca+ 12, 28, target # encoding: [0bAAAAAA10,A,0xfc,0x41]
|
||||
# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
|
||||
# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
|
||||
bca+ 12, 28, target
|
||||
# CHECK-BE: bca- 12, 28, target # encoding: [0x41,0xdc,A,0bAAAAAA10]
|
||||
# CHECK-LE: bca- 12, 28, target # encoding: [0bAAAAAA10,A,0xdc,0x41]
|
||||
# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
|
||||
# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
|
||||
bca- 12, 28, target
|
||||
# CHECK-BE: bcl+ 12, 28, target # encoding: [0x41,0xfc,A,0bAAAAAA01]
|
||||
# CHECK-LE: bcl+ 12, 28, target # encoding: [0bAAAAAA01,A,0xfc,0x41]
|
||||
# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
|
||||
# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
|
||||
bcl+ 12, 28, target
|
||||
# CHECK-BE: bcl- 12, 28, target # encoding: [0x41,0xdc,A,0bAAAAAA01]
|
||||
# CHECK-LE: bcl- 12, 28, target # encoding: [0bAAAAAA01,A,0xdc,0x41]
|
||||
# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
|
||||
# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
|
||||
bcl- 12, 28, target
|
||||
# CHECK-BE: bcla+ 12, 28, target # encoding: [0x41,0xfc,A,0bAAAAAA11]
|
||||
# CHECK-LE: bcla+ 12, 28, target # encoding: [0bAAAAAA11,A,0xfc,0x41]
|
||||
# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
|
||||
# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
|
||||
bcla+ 12, 28, target
|
||||
# CHECK-BE: bcla- 12, 28, target # encoding: [0x41,0xdc,A,0bAAAAAA11]
|
||||
# CHECK-LE: bcla- 12, 28, target # encoding: [0bAAAAAA11,A,0xdc,0x41]
|
||||
# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
|
||||
# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
|
||||
bcla- 12, 28, target
|
||||
|
||||
# CHECK-BE: bclr 4, 10, 3 # encoding: [0x4c,0x8a,0x18,0x20]
|
||||
# CHECK-LE: bclr 4, 10, 3 # encoding: [0x20,0x18,0x8a,0x4c]
|
||||
bclr 4, 10, 3
|
||||
|
Loading…
Reference in New Issue
Block a user