Skip to content

Commit

Permalink
[H2BLB][MC] Connect the MCCodeEmiter
Browse files Browse the repository at this point in the history
Add the encoding information for the simple instruction and
plug the TableGen'erated MCCodeEmitter into the H2BLB MC layer.

This allows to check that the encoding of our instructions are
correct.
  • Loading branch information
qcolombet committed Sep 11, 2024
1 parent 119f987 commit 39095de
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 1 deletion.
2 changes: 2 additions & 0 deletions llvm/lib/Target/H2BLB/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ tablegen(LLVM H2BLBGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM H2BLBGenAsmWriter.inc -gen-asm-writer)
# .s to MCInst
tablegen(LLVM H2BLBGenAsmMatcher.inc -gen-asm-matcher)
# Encoding.
tablegen(LLVM H2BLBGenMCCodeEmitter.inc -gen-emitter)

add_public_tablegen_target(H2BLBCommonTableGen)

Expand Down
25 changes: 24 additions & 1 deletion llvm/lib/Target/H2BLB/H2BLBInstrFormats.td
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
class H2BLBInstruction<string asm, string operands, dag oops = (outs), dag iops = (ins)> : Instruction<> {
class H2BLBInstruction<string asm, string operands,
bits<5> opcode = 0,
bit is32Bit = 0,
dag oops = (outs), dag iops = (ins)>
: Instruction<> {
let Namespace = "H2BLB";
let AsmString = !strconcat(asm, "\t", operands);
let OutOperandList = oops;
let InOperandList = iops;
// Encoding information.
// +---------------------------------------------------------------+
// | Bit index |
// +--------+------------+--------+---------+---------+------------+
// | 15 - 11| 10 | 9 - 7 | 6 - 4 | 3 - 1 | 0 |
// +--------+------------+--------+---------+---------+------------+
// | <5>opc | <1>is32Bit | <3>dst | <3>src0 | <3>src1 | <1><spare> |
// +--------+------------+--------+---------+---------+------------+
bits<16> Inst;
// For oops and iops.
bits<3> dst;
bits<3> src0;
bits<3> src1;
let Inst{15-11} = opcode;
let Inst{10} = is32Bit;
let Inst{9-7} = dst;
let Inst{6-4} = src0;
let Inst{3-1} = src1;
let Inst{0} = 0;
}
2 changes: 2 additions & 0 deletions llvm/lib/Target/H2BLB/H2BLBInstrInfo.td
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
include "H2BLBInstrFormats.td"

def ADDi16rr : H2BLBInstruction<"addi16", "$dst, $src0, $src1",
/*opcode=*/0,
/*is32Bit=*/false,
(outs GPR16:$dst),
(ins GPR16:$src0, GPR16:$src1)>;
1 change: 1 addition & 0 deletions llvm/lib/Target/H2BLB/MCTargetDesc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_llvm_component_library(LLVMH2BLBDesc
H2BLBMCAsmInfo.cpp
H2BLBMCCodeEmitter.cpp
H2BLBMCTargetDesc.cpp
H2BLBInstPrinter.cpp

Expand Down
87 changes: 87 additions & 0 deletions llvm/lib/Target/H2BLB/MCTargetDesc/H2BLBMCCodeEmitter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//===-- H2BLBMCCodeEmitter.cpp - Convert H2BLB code to machine code -------===//
//
// 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 file implements the H2BLBMCCodeEmitter class.
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/H2BLBMCTargetDesc.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/EndianStream.h"
#include <cassert>
#include <cstdint>

using namespace llvm;

#define DEBUG_TYPE "mccodeemitter"

namespace {

class H2BLBMCCodeEmitter : public MCCodeEmitter {
MCContext &MCCtxt;

public:
H2BLBMCCodeEmitter(MCContext &MCCtxt) : MCCodeEmitter(), MCCtxt(MCCtxt) {}
~H2BLBMCCodeEmitter() override = default;

// TableGen'erated function for getting the
// binary encoding for an instruction.
uint64_t getBinaryCodeForInstr(const MCInst &MI,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;

// Return binary encoding of operand. If the machine
// operand requires relocation, record the relocation and return zero.
// This method is used in the TableGen'erated code.
unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;

void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const override;
};

} // end anonymous namespace

MCCodeEmitter *llvm::createH2BLBMCCodeEmitter(const MCInstrInfo &MCII,
MCContext &MCCtxt) {
return new H2BLBMCCodeEmitter(MCCtxt);
}

unsigned
H2BLBMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
if (MO.isReg())
return MCCtxt.getRegisterInfo()->getEncodingValue(MO.getReg());
assert(MO.isImm() && "Unsupported operand type");
return static_cast<unsigned>(MO.getImm());
}

void H2BLBMCCodeEmitter::encodeInstruction(const MCInst &MI,
SmallVectorImpl<char> &CB,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
// Get instruction encoding and emit it
uint64_t Encoding = getBinaryCodeForInstr(MI, Fixups, STI);
assert(((Encoding & 0xffffffffffff0000) == 0) &&
"Only the first 16-bit should be set");
support::endian::write<uint16_t>(CB, Encoding, llvm::endianness::little);
}

#include "H2BLBGenMCCodeEmitter.inc"
4 changes: 4 additions & 0 deletions llvm/lib/Target/H2BLB/MCTargetDesc/H2BLBMCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,8 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeH2BLBTargetMC() {
createH2BLBMCSubtargetInfo);
// Register the MCInst to asm printer.
TargetRegistry::RegisterMCInstPrinter(TheTarget, createH2BLBMCInstPrinter);

// Register the MC code emitter.
TargetRegistry::RegisterMCCodeEmitter(getTheH2BLBTarget(),
createH2BLBMCCodeEmitter);
}
8 changes: 8 additions & 0 deletions llvm/lib/Target/H2BLB/MCTargetDesc/H2BLBMCTargetDesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,16 @@
#ifndef LLVM_LIB_TARGET_H2BLB_MCTARGETDESC_H2BLBMCTARGETDESC_H
#define LLVM_LIB_TARGET_H2BLB_MCTARGETDESC_H2BLBMCTARGETDESC_H

#include "llvm/MC/MCInstrInfo.h"
#include <cstdint> // For int16_t and so on used in the .inc files.

namespace llvm {
class MCContext;
class MCCodeEmitter;
MCCodeEmitter *createH2BLBMCCodeEmitter(const MCInstrInfo &MCII,
MCContext &Ctx);
} // end namespace llvm.

// Defines symbolic names for H2BLB registers. This defines a mapping from
// register name to register number.
#define GET_REGINFO_ENUM
Expand Down
27 changes: 27 additions & 0 deletions llvm/test/MC/H2BLB/addi16.s
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
// RUN: llvm-mc -triple=h2blb %s -o - | FileCheck %s
// RUN: llvm-mc -triple=h2blb %s -o - --show-encoding | FileCheck --check-prefix=ENCODING %s

// For addi16 encoding from high bits to low bits:
// opc<5> = 0
// is32Bit<1> = 0
// dst<3>, src0<3>, src1<3>, <spare==0><1>
// The display of the encoding is low to high, byte per byte.
// So:
// 15 -----7------------- 0
// | | |
// 0b000000<dst><src0><src1>0

// Check that we can parse and print back our only instruction.
// Encoding goes:
// 0b000000<000><001><011>0
// high byte - low byte
// 0b000000<00-0><001><011>0
// => 0x00 - 0x16
// CHECK: addi16 r0, r1, r3
// ENCODING: [0x16,0x00]
addi16 r0, r1, r3

// Add more testing for the encoding.
// Encoding goes:
// 0b000000<011><111><101>0
// high byte - low byte
// 0b000000<01-1><111><101>0
// => 0x01 - 0xfa
// CHECK: addi16 r3, r7, r5
// ENCODING: [0xfa,0x01]
addi16 r3, r7, r5

0 comments on commit 39095de

Please sign in to comment.