117 changes: 117 additions & 0 deletions llvm/lib/Target/Nios2/Nios2InstrFormats.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
//===-- Nios2InstrFormats.td - Nios2 Instruction Formats ---*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Describe NIOS2 instructions format
//
//
//===----------------------------------------------------------------------===//

// Format specifies the encoding used by the instruction. This is part of the
// ad-hoc solution used to emit machine instruction encodings by our machine
// code emitter.
class Format<bits<3> val> {
bits<3> Value = val;
}

def Pseudo : Format<0>;
def FrmI : Format<1>;
def FrmR : Format<2>;
def FrmJ : Format<3>;
def FrmOther : Format<4>; // Instruction w/ a custom format

// Generic Nios2 Format
class Nios2Inst<dag outs, dag ins, string asmstr, list<dag> pattern, Format f>
: Instruction {
field bits<32> Inst;
Format Form = f;

let Namespace = "Nios2";

let Size = 4;

bits<6> Opcode = 0;

// Bottom 6 bits are the 'opcode' field
let Inst{5 - 0} = Opcode;

let OutOperandList = outs;
let InOperandList = ins;

let AsmString = asmstr;
let Pattern = pattern;

//
// Attributes specific to Nios2 instructions:
//
bits<3> FormBits = Form.Value;

// TSFlags layout should be kept in sync with Nios2InstrInfo.h.
let TSFlags{2 - 0} = FormBits;

let DecoderNamespace = "Nios2";
}

// Nios2 Instruction Format
class InstSE<dag outs, dag ins, string asmstr, list<dag> pattern, Format f>
: Nios2Inst<outs, ins, asmstr, pattern, f> {
}

//===----------------------------------------------------------------------===//
// Format I instruction class in Nios2 : <|A|B|immediate|opcode|>
//===----------------------------------------------------------------------===//

class FI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSE<outs, ins, asmstr, pattern, FrmI> {
bits<5> rA;
bits<5> rB;
bits<16> imm;

let Opcode = op;

let Inst{31 - 27} = rA;
let Inst{26 - 22} = rB;
let Inst{21 - 6} = imm;
}

//===----------------------------------------------------------------------===//
// Format R instruction : <|A|B|C|opx|imm|opcode|>
//===----------------------------------------------------------------------===//

class FR<bits<6> opx, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSE<outs, ins, asmstr, pattern, FrmR> {
bits<5> rA;
bits<5> rB;
bits<5> rC;
bits<5> imm = 0;

// opcode is always 0x3a for R instr.
let Opcode = 0x3a;

let Inst{31 - 27} = rA;
let Inst{26 - 22} = rB;
let Inst{21 - 17} = rC;
// opx stands for opcode extension
let Inst{16 - 11} = opx;
// optional 5-bit immediate value
let Inst{10 - 6} = imm;
}

//===----------------------------------------------------------------------===//
// Format J instruction class in Nios2 : <|address|opcode|>
//===----------------------------------------------------------------------===//

class FJ<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern>
: InstSE<outs, ins, asmstr, pattern, FrmJ> {
bits<26> addr;

let Opcode = op;

let Inst{31 - 6} = addr;
}
50 changes: 50 additions & 0 deletions llvm/lib/Target/Nios2/Nios2InstrInfo.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//===- Nios2InstrInfo.td - Target Description for Nios2 ------*- tablegen -*-=//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the Nios2 implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Instruction format superclass
//===----------------------------------------------------------------------===//

include "Nios2InstrFormats.td"

//===----------------------------------------------------------------------===//
// Nios2 Operand, Complex Patterns and Transformations Definitions.
//===----------------------------------------------------------------------===//

def simm16 : Operand<i32> {
let DecoderMethod= "DecodeSimm16";
}

// Node immediate fits as 16-bit sign extended on target immediate.
// e.g. addi, andi
def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;

//===----------------------------------------------------------------------===//
// Instructions specific format
//===----------------------------------------------------------------------===//

// Arithmetic and logical instructions with 2 register operands.
class ArithLogicI<bits<6> op, string instr_asm, SDNode OpNode,
Operand Od, PatLeaf imm_type, RegisterClass RC> :
FI<op, (outs RC:$rB), (ins RC:$rA, Od:$imm16),
!strconcat(instr_asm, "\t$rB, $rA, $imm16"),
[(set RC:$rB, (OpNode RC:$rA, imm_type:$imm16))]> {
let isReMaterializable = 1;
}

//===----------------------------------------------------------------------===//
// Nios2 R1 Instructions
//===----------------------------------------------------------------------===//

/// Arithmetic Instructions (ALU Immediate)
def ADDi : ArithLogicI<0x04, "addi", add, simm16, immSExt16, CPURegs>;
60 changes: 60 additions & 0 deletions llvm/lib/Target/Nios2/Nios2RegisterInfo.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//===-- Nios2RegisterInfo.td - Nios2 Register defs ---------*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// We have bank of 32 registers.
class Nios2Reg<string n> : Register<n> {
field bits<5> Num;
let Namespace = "Nios2";
}

// Nios2 CPU Registers
class Nios2GPRReg<bits<5> num, string n> : Nios2Reg<n> {
let Num = num;
}

//===----------------------------------------------------------------------===//
// Registers
//===----------------------------------------------------------------------===//

let Namespace = "Nios2" in {
// General Purpose Registers
def ZERO : Nios2GPRReg<0, "zero">, DwarfRegNum<[ 0 ]>;
def AT : Nios2GPRReg<1, "at">, DwarfRegNum<[ 1 ]>;
foreach RegNum = 2 - 23 in {
def R #RegNum : Nios2GPRReg<RegNum, "r" #RegNum>, DwarfRegNum<[ RegNum ]>;
}
def ET : Nios2GPRReg<24, "et">, DwarfRegNum<[ 24 ]>;
def BT : Nios2GPRReg<25, "bt">, DwarfRegNum<[ 25 ]>;
def GP : Nios2GPRReg<26, "gp">, DwarfRegNum<[ 26 ]>;
def SP : Nios2GPRReg<27, "sp">, DwarfRegNum<[ 27 ]>;
def FP : Nios2GPRReg<28, "fp">, DwarfRegNum<[ 28 ]>;
def EA : Nios2GPRReg<29, "ea">, DwarfRegNum<[ 29 ]>;
def BA : Nios2GPRReg<30, "ba">, DwarfRegNum<[ 30 ]>;
def RA : Nios2GPRReg<31, "ra">, DwarfRegNum<[ 31 ]>;
def PC : Nios2Reg<"pc">, DwarfRegNum<[ 32 ]>;
}

//===----------------------------------------------------------------------===//
// Register Classes
//===----------------------------------------------------------------------===//

def CPURegs : RegisterClass<"Nios2", [ i32 ], 32,
(add
// Reserved
ZERO,
AT,
// Return Values and Arguments
(sequence "R%u", 2, 7),
// Not preserved across procedure calls
// Caller saved
(sequence "R%u", 8, 15),
// Callee saved
(sequence "R%u", 16, 23),
// Reserved
ET, BT, GP, SP, FP, EA, BA, RA, PC)>;
46 changes: 46 additions & 0 deletions llvm/lib/Target/Nios2/Nios2TargetMachine.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//===-- Nios2TargetMachine.cpp - Define TargetMachine for Nios2 -----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Implements the info about Nios2 target spec.
//
//===----------------------------------------------------------------------===//

#include "Nios2TargetMachine.h"
#include "Nios2.h"

using namespace llvm;

#define DEBUG_TYPE "nios2"

extern "C" void LLVMInitializeNios2Target() {
// Register the target.
}

static std::string computeDataLayout(const Triple &TT, StringRef CPU,
const TargetOptions &Options) {
return "e-p:32:32:32-i8:8:32-i16:16:32-n32";
}

static Reloc::Model getEffectiveRelocModel(CodeModel::Model CM,
Optional<Reloc::Model> RM) {
if (!RM.hasValue() || CM == CodeModel::JITDefault)
return Reloc::Static;
return *RM;
}

Nios2TargetMachine::Nios2TargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
Optional<Reloc::Model> RM,
CodeModel::Model CM,
CodeGenOpt::Level OL)
: LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options), TT, CPU, FS,
Options, getEffectiveRelocModel(CM, RM), CM, OL) {}

Nios2TargetMachine::~Nios2TargetMachine() {}
30 changes: 30 additions & 0 deletions llvm/lib/Target/Nios2/Nios2TargetMachine.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//===-- Nios2TargetMachine.h - Define TargetMachine for Nios2 ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the Nios2 specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_NIOS2_NIOS2TARGETMACHINE_H
#define LLVM_LIB_TARGET_NIOS2_NIOS2TARGETMACHINE_H

#include "llvm/Target/TargetMachine.h"

namespace llvm {
class Nios2TargetMachine : public LLVMTargetMachine {
public:
Nios2TargetMachine(const Target &T, const Triple &TT, StringRef CPU,
StringRef FS, const TargetOptions &Options,
Optional<Reloc::Model> RM, CodeModel::Model CM,
CodeGenOpt::Level OL);
~Nios2TargetMachine() override;
};
} // namespace llvm

#endif
1 change: 1 addition & 0 deletions llvm/lib/Target/Nios2/TargetInfo/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_llvm_library(LLVMNios2Info Nios2TargetInfo.cpp)
23 changes: 23 additions & 0 deletions llvm/lib/Target/Nios2/TargetInfo/LLVMBuild.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
;===- ./lib/Target/Nios2/TargetInfo/LLVMBuild.txt --------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;

[component_0]
type = Library
name = Nios2Info
parent = Nios2
required_libraries = Support
add_to_library_groups = Nios2
24 changes: 24 additions & 0 deletions llvm/lib/Target/Nios2/TargetInfo/Nios2TargetInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===-- Nios2TargetInfo.cpp - Nios2 Target Implementation -----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "Nios2.h"
#include "llvm/Support/TargetRegistry.h"

using namespace llvm;

Target &llvm::getTheNios2Target() {
static Target TheNios2Target;
return TheNios2Target;
}

extern "C" void LLVMInitializeNios2TargetInfo() {
RegisterTarget<Triple::nios2,
/*HasJIT=*/true>
X(getTheNios2Target(), "nios2", "Nios2");
}
3 changes: 3 additions & 0 deletions llvm/test/CodeGen/Nios2/lit.local.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
if not 'Nios2' in config.root.targets:
config.unsupported = True

11 changes: 11 additions & 0 deletions llvm/test/CodeGen/Nios2/target_support.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
; This tests that llc accepts Nios2 target.

; RUN: not not llc < %s -asm-verbose=false -march=nios2 2>&1 | FileCheck %s --check-prefix=ARCH
; RUN: not not llc < %s -asm-verbose=false -mtriple=nios2 2>&1 | FileCheck %s --check-prefix=TRIPLE

; ARCH-NOT: invalid target
; TRIPLE-NOT: unable to get target

define i32 @f(i32 %i) {
ret i32 %i
}