Skip to content

Commit

Permalink
[Xtensa 7/10] Add Xtensa instruction printer
Browse files Browse the repository at this point in the history
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
Andrei Safronov authored and sstefan1 committed Dec 26, 2022
1 parent 52ecf02 commit 2758a01
Show file tree
Hide file tree
Showing 13 changed files with 437 additions and 0 deletions.
4 changes: 4 additions & 0 deletions llvm/lib/Target/Xtensa/CMakeLists.txt
Expand Up @@ -3,6 +3,7 @@ add_llvm_component_group(Xtensa)
set(LLVM_TARGET_DEFINITIONS Xtensa.td)

tablegen(LLVM XtensaGenAsmMatcher.inc -gen-asm-matcher)
tablegen(LLVM XtensaGenAsmWriter.inc -gen-asm-writer)
tablegen(LLVM XtensaGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM XtensaGenMCCodeEmitter.inc -gen-emitter)
tablegen(LLVM XtensaGenRegisterInfo.inc -gen-register-info)
Expand All @@ -14,10 +15,13 @@ add_llvm_target(XtensaCodeGen
XtensaTargetMachine.cpp

LINK_COMPONENTS
AsmPrinter
CodeGen
Core
MC
Support
Target
XtensaDesc
XtensaInfo

ADD_TO_COMPONENT
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
@@ -1,6 +1,7 @@
add_llvm_component_library(LLVMXtensaDesc
XtensaAsmBackend.cpp
XtensaELFObjectWriter.cpp
XtensaInstPrinter.cpp
XtensaMCAsmInfo.cpp
XtensaMCCodeEmitter.cpp
XtensaMCTargetDesc.cpp
Expand Down
107 changes: 107 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
@@ -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);
}
52 changes: 52 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
@@ -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 */
25 changes: 25 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
Expand Up @@ -8,6 +8,7 @@
//
//===----------------------------------------------------------------------===//
#include "XtensaMCTargetDesc.h"
#include "XtensaInstPrinter.h"
#include "XtensaMCAsmInfo.h"
#include "TargetInfo/XtensaTargetInfo.h"
#include "llvm/ADT/STLExtras.h"
Expand All @@ -25,6 +26,9 @@
#define GET_REGINFO_MC_DESC
#include "XtensaGenRegisterInfo.inc"

#define GET_SUBTARGETINFO_MC_DESC
#include "XtensaGenSubtargetInfo.inc"

using namespace llvm;

static MCAsmInfo *createXtensaMCAsmInfo(const MCRegisterInfo &MRI,
Expand All @@ -40,12 +44,25 @@ static MCInstrInfo *createXtensaMCInstrInfo() {
return X;
}

static MCInstPrinter *createXtensaMCInstPrinter(const Triple &TT,
unsigned SyntaxVariant,
const MCAsmInfo &MAI,
const MCInstrInfo &MII,
const MCRegisterInfo &MRI) {
return new XtensaInstPrinter(MAI, MII, MRI);
}

static MCRegisterInfo *createXtensaMCRegisterInfo(const Triple &TT) {
MCRegisterInfo *X = new MCRegisterInfo();
InitXtensaMCRegisterInfo(X, Xtensa::SP);
return X;
}

static MCSubtargetInfo *
createXtensaMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
return createXtensaMCSubtargetInfoImpl(TT, CPU, CPU, FS);
}

extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaTargetMC() {
// Register the MCAsmInfo.
TargetRegistry::RegisterMCAsmInfo(getTheXtensaTarget(), createXtensaMCAsmInfo);
Expand All @@ -57,10 +74,18 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaTargetMC() {
// Register the MCInstrInfo.
TargetRegistry::RegisterMCInstrInfo(getTheXtensaTarget(), createXtensaMCInstrInfo);

// Register the MCInstPrinter.
TargetRegistry::RegisterMCInstPrinter(getTheXtensaTarget(),
createXtensaMCInstPrinter);

// Register the MCRegisterInfo.
TargetRegistry::RegisterMCRegInfo(getTheXtensaTarget(),
createXtensaMCRegisterInfo);

// Register the MCSubtargetInfo.
TargetRegistry::RegisterMCSubtargetInfo(getTheXtensaTarget(),
createXtensaMCSubtargetInfo);

// Register the MCAsmBackend.
TargetRegistry::RegisterMCAsmBackend(getTheXtensaTarget(),
createXtensaMCAsmBackend);
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/Xtensa/Xtensa.td
Expand Up @@ -51,7 +51,13 @@ def XtensaAsmParser : AsmParser {
let ShouldEmitMatchRegisterAltName = 1;
}

def XtensaInstPrinter : AsmWriter {
string AsmWriterClassName = "InstPrinter";
}

def Xtensa : Target {
let InstructionSet = XtensaInstrInfo;
let AssemblyWriters = [XtensaInstPrinter];
let AssemblyParsers = [XtensaAsmParser];
}

84 changes: 84 additions & 0 deletions llvm/test/MC/Xtensa/Core/arith.s
@@ -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

0 comments on commit 2758a01

Please sign in to comment.