[PowerPC] Support extended mnemonics in AsmParser

This patch adds infrastructure to support extended mnemonics in the
PowerPC assembler parser.  It adds support specifically for those
extended mnemonics that LLVM will itself generate.

The test case lists *all* extended mnemonics according to the
PowerPC ISA v2.06 Book I, but marks those not yet supported
as FIXME.

llvm-svn: 181051
This commit is contained in:
Ulrich Weigand 2013-05-03 19:50:27 +00:00
parent 640192daa8
commit d839490f16
3 changed files with 473 additions and 0 deletions

View File

@ -136,6 +136,9 @@ class PPCAsmParser : public MCTargetAsmParser {
MCStreamer &Out, unsigned &ErrorInfo,
bool MatchingInlineAsm);
void ProcessInstruction(MCInst &Inst,
const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
/// @name Auto-generated Match Functions
/// {
@ -413,6 +416,59 @@ void PPCOperand::print(raw_ostream &OS) const {
}
void PPCAsmParser::
ProcessInstruction(MCInst &Inst,
const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
switch (Inst.getOpcode()) {
case PPC::SLWI: {
MCInst TmpInst;
int64_t N = Inst.getOperand(2).getImm();
TmpInst.setOpcode(PPC::RLWINM);
TmpInst.addOperand(Inst.getOperand(0));
TmpInst.addOperand(Inst.getOperand(1));
TmpInst.addOperand(MCOperand::CreateImm(N));
TmpInst.addOperand(MCOperand::CreateImm(0));
TmpInst.addOperand(MCOperand::CreateImm(31 - N));
Inst = TmpInst;
break;
}
case PPC::SRWI: {
MCInst TmpInst;
int64_t N = Inst.getOperand(2).getImm();
TmpInst.setOpcode(PPC::RLWINM);
TmpInst.addOperand(Inst.getOperand(0));
TmpInst.addOperand(Inst.getOperand(1));
TmpInst.addOperand(MCOperand::CreateImm(32 - N));
TmpInst.addOperand(MCOperand::CreateImm(N));
TmpInst.addOperand(MCOperand::CreateImm(31));
Inst = TmpInst;
break;
}
case PPC::SLDI: {
MCInst TmpInst;
int64_t N = Inst.getOperand(2).getImm();
TmpInst.setOpcode(PPC::RLDICR);
TmpInst.addOperand(Inst.getOperand(0));
TmpInst.addOperand(Inst.getOperand(1));
TmpInst.addOperand(MCOperand::CreateImm(N));
TmpInst.addOperand(MCOperand::CreateImm(63 - N));
Inst = TmpInst;
break;
}
case PPC::SRDI: {
MCInst TmpInst;
int64_t N = Inst.getOperand(2).getImm();
TmpInst.setOpcode(PPC::RLDICL);
TmpInst.addOperand(Inst.getOperand(0));
TmpInst.addOperand(Inst.getOperand(1));
TmpInst.addOperand(MCOperand::CreateImm(64 - N));
TmpInst.addOperand(MCOperand::CreateImm(N));
Inst = TmpInst;
break;
}
}
}
bool PPCAsmParser::
MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
@ -423,6 +479,8 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
default: break;
case Match_Success:
// Post-process instructions (typically extended mnemonics)
ProcessInstruction(Inst, Operands);
Inst.setLoc(IDLoc);
Out.EmitInstruction(Inst);
return false;

View File

@ -2111,3 +2111,87 @@ def : Pat<(fma f32:$A, (fneg f32:$C), f32:$B),
include "PPCInstrAltivec.td"
include "PPCInstr64Bit.td"
//===----------------------------------------------------------------------===//
// PowerPC Assembler Instruction Aliases
//
// Pseudo-instructions for alternate assembly syntax (never used by codegen).
// These are aliases that require C++ handling to convert to the target
// instruction, while InstAliases can be handled directly by tblgen.
class PPCAsmPseudo<string asm, dag iops>
: Instruction {
let Namespace = "PPC";
bit PPC64 = 0; // Default value, override with isPPC64
let OutOperandList = (outs);
let InOperandList = iops;
let Pattern = [];
let AsmString = asm;
let isAsmParserOnly = 1;
let isPseudo = 1;
}
def : InstAlias<"mr $rA, $rB", (OR8 g8rc:$rA, g8rc:$rB, g8rc:$rB)>;
def SLWI : PPCAsmPseudo<"slwi $rA, $rS, $n",
(ins gprc:$rA, gprc:$rS, u5imm:$n)>;
def SRWI : PPCAsmPseudo<"srwi $rA, $rS, $n",
(ins gprc:$rA, gprc:$rS, u5imm:$n)>;
def SLDI : PPCAsmPseudo<"sldi $rA, $rS, $n",
(ins g8rc:$rA, g8rc:$rS, u6imm:$n)>;
def SRDI : PPCAsmPseudo<"srdi $rA, $rS, $n",
(ins g8rc:$rA, g8rc:$rS, u6imm:$n)>;
def : InstAlias<"blt $cc, $dst", (BCC 12, crrc:$cc, condbrtarget:$dst)>;
def : InstAlias<"bgt $cc, $dst", (BCC 44, crrc:$cc, condbrtarget:$dst)>;
def : InstAlias<"beq $cc, $dst", (BCC 76, crrc:$cc, condbrtarget:$dst)>;
def : InstAlias<"bun $cc, $dst", (BCC 108, crrc:$cc, condbrtarget:$dst)>;
def : InstAlias<"bso $cc, $dst", (BCC 108, crrc:$cc, condbrtarget:$dst)>;
def : InstAlias<"bge $cc, $dst", (BCC 4, crrc:$cc, condbrtarget:$dst)>;
def : InstAlias<"bnl $cc, $dst", (BCC 4, crrc:$cc, condbrtarget:$dst)>;
def : InstAlias<"ble $cc, $dst", (BCC 36, crrc:$cc, condbrtarget:$dst)>;
def : InstAlias<"bng $cc, $dst", (BCC 36, crrc:$cc, condbrtarget:$dst)>;
def : InstAlias<"bne $cc, $dst", (BCC 68, crrc:$cc, condbrtarget:$dst)>;
def : InstAlias<"bnu $cc, $dst", (BCC 100, crrc:$cc, condbrtarget:$dst)>;
def : InstAlias<"bns $cc, $dst", (BCC 100, crrc:$cc, condbrtarget:$dst)>;
def : InstAlias<"bltlr $cc", (BCLR 12, crrc:$cc)>;
def : InstAlias<"bgtlr $cc", (BCLR 44, crrc:$cc)>;
def : InstAlias<"beqlr $cc", (BCLR 76, crrc:$cc)>;
def : InstAlias<"bunlr $cc", (BCLR 108, crrc:$cc)>;
def : InstAlias<"bsolr $cc", (BCLR 108, crrc:$cc)>;
def : InstAlias<"bgelr $cc", (BCLR 4, crrc:$cc)>;
def : InstAlias<"bnllr $cc", (BCLR 4, crrc:$cc)>;
def : InstAlias<"blelr $cc", (BCLR 36, crrc:$cc)>;
def : InstAlias<"bnglr $cc", (BCLR 36, crrc:$cc)>;
def : InstAlias<"bnelr $cc", (BCLR 68, crrc:$cc)>;
def : InstAlias<"bnulr $cc", (BCLR 100, crrc:$cc)>;
def : InstAlias<"bnslr $cc", (BCLR 100, crrc:$cc)>;
def : InstAlias<"bltctr $cc", (BCCTR 12, crrc:$cc)>;
def : InstAlias<"bgtctr $cc", (BCCTR 44, crrc:$cc)>;
def : InstAlias<"beqctr $cc", (BCCTR 76, crrc:$cc)>;
def : InstAlias<"bunctr $cc", (BCCTR 108, crrc:$cc)>;
def : InstAlias<"bsoctr $cc", (BCCTR 108, crrc:$cc)>;
def : InstAlias<"bgectr $cc", (BCCTR 4, crrc:$cc)>;
def : InstAlias<"bnlctr $cc", (BCCTR 4, crrc:$cc)>;
def : InstAlias<"blectr $cc", (BCCTR 36, crrc:$cc)>;
def : InstAlias<"bngctr $cc", (BCCTR 36, crrc:$cc)>;
def : InstAlias<"bnectr $cc", (BCCTR 68, crrc:$cc)>;
def : InstAlias<"bnuctr $cc", (BCCTR 100, crrc:$cc)>;
def : InstAlias<"bnsctr $cc", (BCCTR 100, crrc:$cc)>;
def : InstAlias<"bltctrl $cc", (BCCTRL 12, crrc:$cc)>;
def : InstAlias<"bgtctrl $cc", (BCCTRL 44, crrc:$cc)>;
def : InstAlias<"beqctrl $cc", (BCCTRL 76, crrc:$cc)>;
def : InstAlias<"bunctrl $cc", (BCCTRL 108, crrc:$cc)>;
def : InstAlias<"bsoctrl $cc", (BCCTRL 108, crrc:$cc)>;
def : InstAlias<"bgectrl $cc", (BCCTRL 4, crrc:$cc)>;
def : InstAlias<"bnlctrl $cc", (BCCTRL 4, crrc:$cc)>;
def : InstAlias<"blectrl $cc", (BCCTRL 36, crrc:$cc)>;
def : InstAlias<"bngctrl $cc", (BCCTRL 36, crrc:$cc)>;
def : InstAlias<"bnectrl $cc", (BCCTRL 68, crrc:$cc)>;
def : InstAlias<"bnuctrl $cc", (BCCTRL 100, crrc:$cc)>;
def : InstAlias<"bnsctrl $cc", (BCCTRL 100, crrc:$cc)>;

View File

@ -0,0 +1,331 @@
# RUN: llvm-mc -triple powerpc64-unknown-unknown --show-encoding %s | FileCheck %s
# FIXME: Condition register bit symbols
# Branch mnemonics
# CHECK: blr # encoding: [0x4e,0x80,0x00,0x20]
blr
# CHECK: bctr # encoding: [0x4e,0x80,0x04,0x20]
bctr
# FIXME: blrl
# CHECK: bctrl # encoding: [0x4e,0x80,0x04,0x21]
bctrl
# FIXME: bt 2, target
# FIXME: bta 2, target
# FIXME: btlr 2
# FIXME: btctr 2
# FIXME: btl 2, target
# FIXME: btla 2, target
# FIXME: btlrl 2
# FIXME: btctrl 2
# FIXME: bf 2, target
# FIXME: bfa 2, target
# FIXME: bflr 2
# FIXME: bfctr 2
# FIXME: bfl 2, target
# FIXME: bfla 2, target
# FIXME: bflrl 2
# FIXME: bfctrl 2
# CHECK: bdnz target # encoding: [0x42,0x00,A,0bAAAAAA00]
# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
bdnz target
# FIXME: bdnza target
# CHECK: bdnzlr # encoding: [0x4e,0x00,0x00,0x20]
bdnzlr
# FIXME: bdnzl target
# FIXME: bdnzla target
# FIXME: bdnzlrl
# FIXME: bdnzt 2, target
# FIXME: bdnzta 2, target
# FIXME: bdnztlr 2
# FIXME: bdnztl 2, target
# FIXME: bdnztla 2, target
# FIXME: bdnztlrl 2
# FIXME: bdnzf 2, target
# FIXME: bdnzfa 2, target
# FIXME: bdnzflr 2
# FIXME: bdnzfl 2, target
# FIXME: bdnzfla 2, target
# FIXME: bdnzflrl 2
# CHECK: bdz target # encoding: [0x42,0x40,A,0bAAAAAA00]
# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
bdz target
# FIXME: bdza target
# CHECK: bdzlr # encoding: [0x4e,0x40,0x00,0x20]
bdzlr
# FIXME: bdzl target
# FIXME: bdzla target
# FIXME: bdzlrl
# FIXME: bdzt 2, target
# FIXME: bdzta 2, target
# FIXME: bdztlr 2
# FIXME: bdztl 2, target
# FIXME: bdztla 2, target
# FIXME: bdztlrl 2
# FIXME: bdzf 2, target
# FIXME: bdzfa 2, target
# FIXME: bdzflr 2
# FIXME: bdzfl 2, target
# FIXME: bdzfla 2, target
# FIXME: bdzflrl 2
# CHECK: blt 2, target # encoding: [0x41,0x88,A,0bAAAAAA00]
# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
blt 2, target
# FIXME: blta 2, target
# CHECK: bltlr 2 # encoding: [0x4d,0x88,0x00,0x20]
bltlr 2
# CHECK: bltctr 2 # encoding: [0x4d,0x88,0x04,0x20]
bltctr 2
# FIXME: bltl 2, target
# FIXME: bltla 2, target
# FIXME: bltlrl 2
# CHECK: bltctrl 2 # encoding: [0x4d,0x88,0x04,0x21]
bltctrl 2
# CHECK: ble 2, target # encoding: [0x40,0x89,A,0bAAAAAA00]
# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
ble 2, target
# FIXME: blea 2, target
# CHECK: blelr 2 # encoding: [0x4c,0x89,0x00,0x20]
blelr 2
# CHECK: blectr 2 # encoding: [0x4c,0x89,0x04,0x20]
blectr 2
# FIXME: blel 2, target
# FIXME: blela 2, target
# FIXME: blelrl 2
# CHECK: blectrl 2 # encoding: [0x4c,0x89,0x04,0x21]
blectrl 2
# CHECK: beq 2, target # encoding: [0x41,0x8a,A,0bAAAAAA00]
# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
beq 2, target
# FIXME: beqa 2, target
# CHECK: beqlr 2 # encoding: [0x4d,0x8a,0x00,0x20]
beqlr 2
# CHECK: beqctr 2 # encoding: [0x4d,0x8a,0x04,0x20]
beqctr 2
# FIXME: beql 2, target
# FIXME: beqla 2, target
# FIXME: beqlrl 2
# CHECK: beqctrl 2 # encoding: [0x4d,0x8a,0x04,0x21]
beqctrl 2
# CHECK: bge 2, target # encoding: [0x40,0x88,A,0bAAAAAA00]
# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
bge 2, target
# FIXME: bgea 2, target
# CHECK: bgelr 2 # encoding: [0x4c,0x88,0x00,0x20]
bgelr 2
# CHECK: bgectr 2 # encoding: [0x4c,0x88,0x04,0x20]
bgectr 2
# FIXME: bgel 2, target
# FIXME: bgela 2, target
# FIXME: bgelrl 2
# CHECK: bgectrl 2 # encoding: [0x4c,0x88,0x04,0x21]
bgectrl 2
# CHECK: bgt 2, target # encoding: [0x41,0x89,A,0bAAAAAA00]
# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
bgt 2, target
# FIXME: bgta 2, target
# CHECK: bgtlr 2 # encoding: [0x4d,0x89,0x00,0x20]
bgtlr 2
# CHECK: bgtctr 2 # encoding: [0x4d,0x89,0x04,0x20]
bgtctr 2
# FIXME: bgtl 2, target
# FIXME: bgtla 2, target
# FIXME: bgtlrl 2
# CHECK: bgtctrl 2 # encoding: [0x4d,0x89,0x04,0x21]
bgtctrl 2
# CHECK: bge 2, target # encoding: [0x40,0x88,A,0bAAAAAA00]
# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
bnl 2, target
# FIXME: bnla 2, target
# CHECK: bgelr 2 # encoding: [0x4c,0x88,0x00,0x20]
bnllr 2
# CHECK: bgectr 2 # encoding: [0x4c,0x88,0x04,0x20]
bnlctr 2
# FIXME: bnll 2, target
# FIXME: bnlla 2, target
# FIXME: bnllrl 2
# CHECK: bgectrl 2 # encoding: [0x4c,0x88,0x04,0x21]
bnlctrl 2
# CHECK: bne 2, target # encoding: [0x40,0x8a,A,0bAAAAAA00]
# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
bne 2, target
# FIXME: bnea 2, target
# CHECK: bnelr 2 # encoding: [0x4c,0x8a,0x00,0x20]
bnelr 2
# CHECK: bnectr 2 # encoding: [0x4c,0x8a,0x04,0x20]
bnectr 2
# FIXME: bnel 2, target
# FIXME: bnela 2, target
# FIXME: bnelrl 2
# CHECK: bnectrl 2 # encoding: [0x4c,0x8a,0x04,0x21]
bnectrl 2
# CHECK: ble 2, target # encoding: [0x40,0x89,A,0bAAAAAA00]
# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
bng 2, target
# FIXME: bnga 2, target
# CHECK: blelr 2 # encoding: [0x4c,0x89,0x00,0x20]
bnglr 2
# CHECK: blectr 2 # encoding: [0x4c,0x89,0x04,0x20]
bngctr 2
# FIXME: bngl 2, target
# FIXME: bngla 2, target
# FIXME: bnglrl 2
# CHECK: blectrl 2 # encoding: [0x4c,0x89,0x04,0x21]
bngctrl 2
# CHECK: bun 2, target # encoding: [0x41,0x8b,A,0bAAAAAA00]
# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
bso 2, target
# FIXME: bsoa 2, target
# CHECK: bunlr 2 # encoding: [0x4d,0x8b,0x00,0x20]
bsolr 2
# CHECK: bunctr 2 # encoding: [0x4d,0x8b,0x04,0x20]
bsoctr 2
# FIXME: bsol 2, target
# FIXME: bsola 2, target
# FIXME: bsolrl 2
# CHECK: bunctrl 2 # encoding: [0x4d,0x8b,0x04,0x21]
bsoctrl 2
# CHECK: bnu 2, target # encoding: [0x40,0x8b,A,0bAAAAAA00]
# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
bns 2, target
# FIXME: bnsa 2, target
# CHECK: bnulr 2 # encoding: [0x4c,0x8b,0x00,0x20]
bnslr 2
# CHECK: bnuctr 2 # encoding: [0x4c,0x8b,0x04,0x20]
bnsctr 2
# FIXME: bnsl 2, target
# FIXME: bnsla 2, target
# FIXME: bnslrl 2
# CHECK: bnuctrl 2 # encoding: [0x4c,0x8b,0x04,0x21]
bnsctrl 2
# CHECK: bun 2, target # encoding: [0x41,0x8b,A,0bAAAAAA00]
# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
bun 2, target
# FIXME: buna 2, target
# CHECK: bunlr 2 # encoding: [0x4d,0x8b,0x00,0x20]
bunlr 2
# CHECK: bunctr 2 # encoding: [0x4d,0x8b,0x04,0x20]
bunctr 2
# FIXME: bunl 2, target
# FIXME: bunla 2, target
# FIXME: bunlrl 2
# CHECK: bunctrl 2 # encoding: [0x4d,0x8b,0x04,0x21]
bunctrl 2
# CHECK: bnu 2, target # encoding: [0x40,0x8b,A,0bAAAAAA00]
# CHECK-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
bnu 2, target
# FIXME: bnua 2, target
# CHECK: bnulr 2 # encoding: [0x4c,0x8b,0x00,0x20]
bnulr 2
# CHECK: bnuctr 2 # encoding: [0x4c,0x8b,0x04,0x20]
bnuctr 2
# FIXME: bnul 2, target
# FIXME: bnula 2, target
# FIXME: bnulrl 2
# CHECK: bnuctrl 2 # encoding: [0x4c,0x8b,0x04,0x21]
bnuctrl 2
# FIXME: Condition register logical mnemonics
# FIXME: Subtract mnemonics
# Compare mnemonics
# CHECK: cmpdi 2, 3, 128 # encoding: [0x2d,0x23,0x00,0x80]
cmpdi 2, 3, 128
# CHECK: cmpd 2, 3, 4 # encoding: [0x7d,0x23,0x20,0x00]
cmpd 2, 3, 4
# CHECK: cmpldi 2, 3, 128 # encoding: [0x29,0x23,0x00,0x80]
cmpldi 2, 3, 128
# CHECK: cmpld 2, 3, 4 # encoding: [0x7d,0x23,0x20,0x40]
cmpld 2, 3, 4
# CHECK: cmpwi 2, 3, 128 # encoding: [0x2d,0x03,0x00,0x80]
cmpwi 2, 3, 128
# CHECK: cmpw 2, 3, 4 # encoding: [0x7d,0x03,0x20,0x00]
cmpw 2, 3, 4
# CHECK: cmplwi 2, 3, 128 # encoding: [0x29,0x03,0x00,0x80]
cmplwi 2, 3, 128
# CHECK: cmplw 2, 3, 4 # encoding: [0x7d,0x03,0x20,0x40]
cmplw 2, 3, 4
# FIXME: Trap mnemonics
# Rotate and shift mnemonics
# FIXME: extldi 2, 3, 4, 5
# FIXME: extrdi 2, 3, 4, 5
# FIXME: insrdi 2, 3, 4, 5
# FIXME: rotldi 2, 3, 4
# FIXME: rotrdi 2, 3, 4
# FIXME: rotld 2, 3, 4
# CHECK: sldi 2, 3, 4 # encoding: [0x78,0x62,0x26,0xe4]
sldi 2, 3, 4
# CHECK: rldicl 2, 3, 60, 4 # encoding: [0x78,0x62,0xe1,0x02]
srdi 2, 3, 4
# FIXME: clrldi 2, 3, 4
# FIXME: clrrdi 2, 3, 4
# FIXME: clrlsldi 2, 3, 4, 5
# FIXME: extlwi 2, 3, 4, 5
# FIXME: extrwi 2, 3, 4, 5
# FIXME: inslwi 2, 3, 4, 5
# FIXME: insrwi 2, 3, 4, 5
# FIXME: rotlwi 2, 3, 4
# FIXME: rotrwi 2, 3, 4
# FIXME: rotlw 2, 3, 4
# CHECK: slwi 2, 3, 4 # encoding: [0x54,0x62,0x20,0x36]
slwi 2, 3, 4
# CHECK: srwi 2, 3, 4 # encoding: [0x54,0x62,0xe1,0x3e]
srwi 2, 3, 4
# FIXME: clrlwi 2, 3, 4
# FIXME: clrrwi 2, 3, 4
# FIXME: clrlslwi 2, 3, 4, 5
# Move to/from special purpose register mnemonics
# FIXME: mtxer 2
# FIXME: mfxer 2
# CHECK: mtlr 2 # encoding: [0x7c,0x48,0x03,0xa6]
mtlr 2
# CHECK: mflr 2 # encoding: [0x7c,0x48,0x02,0xa6]
mflr 2
# CHECK: mtctr 2 # encoding: [0x7c,0x49,0x03,0xa6]
mtctr 2
# CHECK: mfctr 2 # encoding: [0x7c,0x49,0x02,0xa6]
mfctr 2
# Miscellaneous mnemonics
# CHECK: nop # encoding: [0x60,0x00,0x00,0x00]
nop
# FIXME: xnop
# CHECK: li 2, 128 # encoding: [0x38,0x40,0x00,0x80]
li 2, 128
# CHECK: lis 2, 128 # encoding: [0x3c,0x40,0x00,0x80]
lis 2, 128
# FIXME: la 2, 128(4)
# CHECK: mr 2, 3 # encoding: [0x7c,0x62,0x1b,0x78]
mr 2, 3
# FIXME: not 2, 3