Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Xtensa 7/10] Add Xtensa instruction printer
Add printer for current instructions and operands subsets. Also add basic tests of the Xtensa instructions. Differential Revision: https://reviews.llvm.org/D64833
- Loading branch information
Showing
13 changed files
with
437 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
//===- XtensaInstPrinter.cpp - Convert Xtensa MCInst to asm syntax --------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This class prints an Xtensa MCInst to a .s file. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "XtensaInstPrinter.h" | ||
#include "llvm/CodeGen/MachineOperand.h" | ||
#include "llvm/MC/MCExpr.h" | ||
#include "llvm/MC/MCInstrInfo.h" | ||
#include "llvm/MC/MCSymbol.h" | ||
#include "llvm/Support/Casting.h" | ||
#include "llvm/Support/raw_ostream.h" | ||
|
||
using namespace llvm; | ||
|
||
#define DEBUG_TYPE "asm-printer" | ||
|
||
#include "XtensaGenAsmWriter.inc" | ||
|
||
static void printExpr(const MCExpr *Expr, raw_ostream &OS) { | ||
int Offset = 0; | ||
const MCSymbolRefExpr *SRE; | ||
|
||
if (!(SRE = cast<MCSymbolRefExpr>(Expr))) | ||
assert(false && "Unexpected MCExpr type."); | ||
|
||
MCSymbolRefExpr::VariantKind Kind = SRE->getKind(); | ||
|
||
switch (Kind) { | ||
case MCSymbolRefExpr::VK_None: | ||
break; | ||
// TODO | ||
default: | ||
report_fatal_error("Invalid kind!"); | ||
} | ||
|
||
OS << SRE->getSymbol(); | ||
|
||
if (Offset) { | ||
if (Offset > 0) | ||
OS << '+'; | ||
OS << Offset; | ||
} | ||
|
||
if (Kind != MCSymbolRefExpr::VK_None) | ||
OS << ')'; | ||
} | ||
|
||
void XtensaInstPrinter::printOperand(const MCOperand &MC, raw_ostream &O) { | ||
if (MC.isReg()) | ||
O << getRegisterName(MC.getReg()); | ||
else if (MC.isImm()) | ||
O << MC.getImm(); | ||
else if (MC.isExpr()) | ||
printExpr(MC.getExpr(), O); | ||
else | ||
report_fatal_error("Invalid operand"); | ||
} | ||
|
||
void XtensaInstPrinter::printInst(const MCInst *MI, uint64_t Address, | ||
StringRef Annot, const MCSubtargetInfo &STI, | ||
raw_ostream &O) { | ||
printInstruction(MI, Address, O); | ||
printAnnotation(O, Annot); | ||
} | ||
|
||
void XtensaInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const { | ||
O << getRegisterName(RegNo); | ||
} | ||
|
||
void XtensaInstPrinter::printOperand(const MCInst *MI, int OpNum, | ||
raw_ostream &O) { | ||
printOperand(MI->getOperand(OpNum), O); | ||
} | ||
|
||
void XtensaInstPrinter::printImm8_AsmOperand(const MCInst *MI, int OpNum, | ||
raw_ostream &O) { | ||
if (MI->getOperand(OpNum).isImm()) { | ||
int64_t Value = MI->getOperand(OpNum).getImm(); | ||
assert(isInt<8>(Value) && | ||
"Invalid argument, value must be in ranges [-128,127]"); | ||
O << Value; | ||
} else { | ||
printOperand(MI, OpNum, O); | ||
} | ||
} | ||
|
||
void XtensaInstPrinter::printImm8_sh8_AsmOperand(const MCInst *MI, int OpNum, | ||
raw_ostream &O) { | ||
if (MI->getOperand(OpNum).isImm()) { | ||
int64_t Value = MI->getOperand(OpNum).getImm(); | ||
assert((isInt<16>(Value) && ((Value & 0xFF) == 0)) && | ||
"Invalid argument, value must be multiples of 256 in range " | ||
"[-32768,32512]"); | ||
O << Value; | ||
} else | ||
printOperand(MI, OpNum, O); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
//===- XtensaInstPrinter.h - Convert Xtensa MCInst to asm syntax -*- C++ -*-==// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This class prints an Xtensa MCInst to a .s file. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAINSTPRINTER_H | ||
#define LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAINSTPRINTER_H | ||
|
||
#include "llvm/MC/MCInstPrinter.h" | ||
#include "llvm/Support/Compiler.h" | ||
|
||
namespace llvm { | ||
class MCOperand; | ||
|
||
class XtensaInstPrinter : public MCInstPrinter { | ||
public: | ||
XtensaInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, | ||
const MCRegisterInfo &MRI) | ||
: MCInstPrinter(MAI, MII, MRI) {} | ||
|
||
// Automatically generated by tblgen. | ||
std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override; | ||
void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); | ||
static const char *getRegisterName(unsigned RegNo); | ||
|
||
// Print the given operand. | ||
static void printOperand(const MCOperand &MO, raw_ostream &O); | ||
|
||
// Override MCInstPrinter. | ||
void printRegName(raw_ostream &O, unsigned RegNo) const override; | ||
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, | ||
const MCSubtargetInfo &STI, raw_ostream &O) override; | ||
|
||
private: | ||
// Print various types of operand. | ||
void printOperand(const MCInst *MI, int OpNum, raw_ostream &O); | ||
|
||
void printImm8_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O); | ||
void printImm8_sh8_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O); | ||
}; | ||
} // end namespace llvm | ||
|
||
#endif /* LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAINSTPRINTER_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# RUN: llvm-mc %s -triple=xtensa -show-encoding \ | ||
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s | ||
|
||
|
||
.align 4 | ||
LBL0: | ||
|
||
# Instruction format RRR | ||
# CHECK-INST: abs a5, a6 | ||
# CHECK: encoding: [0x60,0x51,0x60] | ||
abs a5, a6 | ||
|
||
# Instruction format RRR | ||
# CHECK-INST: add a3, a9, a4 | ||
# CHECK: encoding: [0x40,0x39,0x80] | ||
add a3, a9, a4 | ||
|
||
# CHECK-INST: add a15, a9, a1 | ||
# CHECK: encoding: [0x10,0xf9,0x80] | ||
add a15, a9, sp | ||
|
||
# Instruction format RRI8 | ||
# CHECK-INST: addi a8, a1, -128 | ||
# CHECK: encoding: [0x82,0xc1,0x80] | ||
addi a8, sp, -128 | ||
|
||
# CHECK-INST: addi a8, a1, -12 | ||
# CHECK: encoding: [0x82,0xc1,0xf4] | ||
addi a8, a1, -12 | ||
|
||
# Instruction format RRI8 | ||
# CHECK-INST: addmi a1, a2, 32512 | ||
# CHECK: encoding: [0x12,0xd2,0x7f] | ||
addmi a1, a2, 32512 | ||
|
||
# Instruction format RRR | ||
# CHECK-INST: addx2 a2, a1, a5 | ||
# CHECK: encoding: [0x50,0x21,0x90] | ||
addx2 a2, sp, a5 | ||
|
||
# Instruction format RRR | ||
# CHECK-INST: addx4 a3, a1, a6 | ||
# CHECK: encoding: [0x60,0x31,0xa0] | ||
addx4 a3, sp, a6 | ||
|
||
# Instruction format RRR | ||
# CHECK-INST: addx8 a4, a1, a7 | ||
# CHECK: encoding: [0x70,0x41,0xb0] | ||
addx8 a4, sp, a7 | ||
|
||
# Instruction format RRR | ||
# CHECK-INST: neg a1, a3 | ||
# CHECK: encoding: [0x30,0x10,0x60] | ||
neg a1, a3 | ||
|
||
# Instruction format RRR | ||
# CHECK-INST: or a4, a5, a6 | ||
# CHECK: encoding: [0x60,0x45,0x20] | ||
or a4, a5, a6 | ||
|
||
# Instruction format RRR | ||
# CHECK-INST: sub a8, a2, a1 | ||
# CHECK: encoding: [0x10,0x82,0xc0] | ||
sub a8, a2, a1 | ||
|
||
# Instruction format RRR | ||
# CHECK-INST: subx2 a2, a1, a5 | ||
# CHECK: encoding: [0x50,0x21,0xd0] | ||
subx2 a2, sp, a5 | ||
|
||
# Instruction format RRR | ||
# CHECK-INST: subx4 a3, a1, a6 | ||
# CHECK: encoding: [0x60,0x31,0xe0] | ||
subx4 a3, sp, a6 | ||
|
||
# Instruction format RRR | ||
# CHECK-INST: subx8 a4, a1, a7 | ||
# CHECK: encoding: [0x70,0x41,0xf0] | ||
subx8 a4, sp, a7 | ||
|
||
# Instruction format RRR | ||
# CHECK-INST: xor a6, a4, a5 | ||
# CHECK: encoding: [0x50,0x64,0x30] | ||
xor a6, a4, a5 |
Oops, something went wrong.