lots of errors
This commit is contained in:
@@ -51,6 +51,17 @@ namespace Harp {
|
||||
private:
|
||||
Size n, o, r, p, i1, i2, i3;
|
||||
Word oMask, rMask, pMask, i1Mask, i2Mask, i3Mask;
|
||||
|
||||
// FARES
|
||||
Size inst_s, opcode_s, reg_s, func3_s;
|
||||
Size shift_opcode, shift_rd, shift_rs1, shift_rs2, shift_func3, shift_func7;
|
||||
Size shift_j_u_immed, shift_s_b_immed, shift_i_immed;
|
||||
|
||||
|
||||
|
||||
Word reg_mask, func3_mask, func7_mask, opcode_mask, i_immed_mask,
|
||||
s_immed_mask, b_immed_mask, u_immed_mask, j_immed_mask;
|
||||
|
||||
};
|
||||
|
||||
class ByteDecoder : public Decoder {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#ifndef __INSTRUCTION_H
|
||||
#define __INSTRUCTION_H
|
||||
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
#include "types.h"
|
||||
@@ -24,34 +25,52 @@ namespace Harp {
|
||||
|
||||
class Instruction {
|
||||
public:
|
||||
enum Opcode { NOP, DI, EI, TLBADD, TLBFLUSH, NEG, NOT, AND,
|
||||
OR, XOR, ADD, SUB, MUL, DIV, MOD, SHL,
|
||||
SHR, ANDI, ORI, XORI, ADDI, SUBI, MULI, DIVI,
|
||||
MODI, SHLI, SHRI, JALI, JALR, JMPI, JMPR, CLONE,
|
||||
JALIS, JALRS, JMPRT, LD, ST, LDI, RTOP, ANDP,
|
||||
ORP, XORP, NOTP, ISNEG, ISZERO, HALT, TRAP, JMPRU,
|
||||
SKEP, RETI, TLBRM, ITOF, FTOI, FADD, FSUB, FMUL,
|
||||
FDIV, FNEG, WSPAWN, SPLIT, JOIN, BAR };
|
||||
enum ArgClass {
|
||||
AC_NONE, AC_2REG, AC_2IMM, AC_3REG, AC_3PREG, AC_3IMM, AC_3REGSRC,
|
||||
AC_1IMM, AC_1REG, AC_3IMMSRC, AC_PREG_REG, AC_2PREG, AC_2REGSRC
|
||||
};
|
||||
enum InstType {
|
||||
ITYPE_NULL, ITYPE_INTBASIC, ITYPE_INTMUL, ITYPE_INTDIV, ITYPE_STACK, ITYPE_BR,
|
||||
ITYPE_CALL, ITYPE_RET, ITYPE_TRAP, ITYPE_FPBASIC, ITYPE_FPMUL, ITYPE_FPDIV
|
||||
};
|
||||
enum Opcode
|
||||
{
|
||||
NOP = 0,
|
||||
R_INST = 51,
|
||||
L_INST = 3,
|
||||
I_INST = 19,
|
||||
S_INST = 35,
|
||||
B_INST = 99,
|
||||
LUI_INST = 55,
|
||||
AUIPC_INST = 23,
|
||||
JAL_INST = 111,
|
||||
JALR_INST = 103,
|
||||
SYS_INST = 115
|
||||
};
|
||||
|
||||
enum InstType { N_TYPE, R_TYPE, I_TYPE, S_TYPE, B_TYPE, U_TYPE, J_TYPE };
|
||||
|
||||
// We build a table of instruction information out of this.
|
||||
static struct InstTableEntry {
|
||||
struct InstTableEntry_t {
|
||||
const char *opString;
|
||||
bool controlFlow, relAddress, allSrcArgs, privileged;
|
||||
ArgClass argClass;
|
||||
InstType iType;
|
||||
} instTable[];
|
||||
|
||||
};
|
||||
|
||||
Instruction() :
|
||||
predicated(false), nRsrc(0), nPsrc(0), immsrcPresent(false),
|
||||
rdestPresent(false), pdestPresent(false), refLiteral(NULL) {}
|
||||
rdestPresent(false), pdestPresent(false), refLiteral(NULL)
|
||||
{
|
||||
|
||||
instTable = std::map<int, struct InstTableEntry_t>
|
||||
{
|
||||
{Opcode::NOP, {"nop" , false, false, false, false, InstType::N_TYPE }},
|
||||
{Opcode::R_INST, {"r_type", false, false, false, false, InstType::R_TYPE }},
|
||||
{Opcode::L_INST, {"load" , false, false, false, false, InstType::I_TYPE }},
|
||||
{Opcode::I_INST, {"i_type", false, false, false, false, InstType::I_TYPE }},
|
||||
{Opcode::S_INST, {"store" , false, false, false, false, InstType::I_TYPE }},
|
||||
{Opcode::B_INST, {"branch", true , false, false, false, InstType::B_TYPE }},
|
||||
{Opcode::LUI_INST, {"lui" , false, false, false, false, InstType::U_TYPE }},
|
||||
{Opcode::AUIPC_INST, {"auipc" , false, false, false, false, InstType::U_TYPE }},
|
||||
{Opcode::JAL_INST, {"jal" , true , false, false, false, InstType::J_TYPE }},
|
||||
{Opcode::JALR_INST, {"jalr" , true , false, false, false, InstType::I_TYPE }},
|
||||
{Opcode::SYS_INST, {"SYS" , true , false, false, false, InstType::I_TYPE }}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void executeOn(Warp &warp);
|
||||
friend std::ostream &operator<<(std::ostream &, Instruction &);
|
||||
@@ -61,6 +80,8 @@ namespace Harp {
|
||||
void setPred (RegNum pReg) { predicated = true; pred = pReg; }
|
||||
void setDestReg (RegNum destReg) { rdestPresent = true; rdest = destReg; }
|
||||
void setSrcReg (RegNum srcReg) { rsrc[nRsrc++] = srcReg; }
|
||||
void setFunc3 (Word func3) { this->func3 = func3; }
|
||||
void setFunc7 (Word func7) { this->func7 = func7; }
|
||||
void setDestPReg(RegNum dPReg) { pdestPresent = true; pdest = dPReg; }
|
||||
void setSrcPReg (RegNum srcPReg) { psrc[nPsrc++] = srcPReg; }
|
||||
Word *setSrcImm () { immsrcPresent = true; immsrc = 0xa5; return &immsrc;}
|
||||
@@ -85,7 +106,7 @@ namespace Harp {
|
||||
Ref *getRefLiteral() const { return refLiteral; }
|
||||
|
||||
/* Getters used as table lookup. */
|
||||
bool hasRelImm() const { return instTable[op].relAddress; }
|
||||
bool hasRelImm() const { return (*(instTable.find(op))).second.relAddress; }
|
||||
|
||||
private:
|
||||
bool predicated;
|
||||
@@ -95,10 +116,22 @@ namespace Harp {
|
||||
RegNum rsrc[MAX_REG_SOURCES], psrc[MAX_PRED_SOURCES];
|
||||
bool immsrcPresent;
|
||||
Word immsrc;
|
||||
Word func3;
|
||||
Word func7;
|
||||
bool rdestPresent, pdestPresent;
|
||||
RegNum rdest, pdest;
|
||||
Ref *refLiteral;
|
||||
|
||||
public:
|
||||
static std::map<int, struct InstTableEntry_t> instTable;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// static struct InstTableEntry {
|
||||
// const char *opString;
|
||||
// bool controlFlow, relAddress, allSrcArgs, privileged;
|
||||
// InstType iType;
|
||||
// };
|
||||
@@ -16,195 +16,195 @@
|
||||
#include "enc.h"
|
||||
#include "asm-tokens.h"
|
||||
|
||||
namespace Harp {
|
||||
class Decoder;
|
||||
class Encoder;
|
||||
// namespace Harp {
|
||||
// class Decoder;
|
||||
// class Encoder;
|
||||
|
||||
class Ref {
|
||||
public:
|
||||
std::string name;
|
||||
Ref(const std::string &n, bool r, Size ib = 0):
|
||||
name(n), bound(false), relative(r), ibase(ib) { }
|
||||
virtual ~Ref() { }
|
||||
virtual void bind(Addr addr, Addr base = 0) = 0;
|
||||
virtual Addr getAddr() const = 0;
|
||||
// class Ref {
|
||||
// public:
|
||||
// std::string name;
|
||||
// Ref(const std::string &n, bool r, Size ib = 0):
|
||||
// name(n), bound(false), relative(r), ibase(ib) { }
|
||||
// virtual ~Ref() { }
|
||||
// virtual void bind(Addr addr, Addr base = 0) = 0;
|
||||
// virtual Addr getAddr() const = 0;
|
||||
|
||||
bool bound, relative;
|
||||
Size ibase;
|
||||
};
|
||||
// bool bound, relative;
|
||||
// Size ibase;
|
||||
// };
|
||||
|
||||
/* Used in not-yet-encoded code objects, plain old data. */
|
||||
class SimpleRef : public Ref {
|
||||
public:
|
||||
SimpleRef(const std::string &name, Addr &addr, bool rel = false) :
|
||||
Ref(name, rel), addr(addr) { }
|
||||
virtual void bind(Addr addr, Addr base = 0) {
|
||||
std::cout << "Attempted to bind a SimpleRef.\n";
|
||||
exit(1);
|
||||
}
|
||||
virtual Addr getAddr() const { return this->addr; }
|
||||
Byte *getAddrPtr() { return (Byte*)&addr; }
|
||||
// /* Used in not-yet-encoded code objects, plain old data. */
|
||||
// class SimpleRef : public Ref {
|
||||
// public:
|
||||
// SimpleRef(const std::string &name, Addr &addr, bool rel = false) :
|
||||
// Ref(name, rel), addr(addr) { }
|
||||
// virtual void bind(Addr addr, Addr base = 0) {
|
||||
// std::cout << "Attempted to bind a SimpleRef.\n";
|
||||
// exit(1);
|
||||
// }
|
||||
// virtual Addr getAddr() const { return this->addr; }
|
||||
// Byte *getAddrPtr() { return (Byte*)&addr; }
|
||||
|
||||
private:
|
||||
Addr &addr;
|
||||
};
|
||||
// private:
|
||||
// Addr &addr;
|
||||
// };
|
||||
|
||||
/* Used in already-encoded code objects. */
|
||||
class OffsetRef : public Ref {
|
||||
public:
|
||||
OffsetRef(
|
||||
const std::string &name, std::vector<Byte> &v, Size offset, Size bits,
|
||||
Size ws, bool rel = false, Size ibase = 0
|
||||
) : Ref(name, rel, ibase), data(v), offset(offset), bits(bits), wordSize(ws)
|
||||
{}
|
||||
// /* Used in already-encoded code objects. */
|
||||
// class OffsetRef : public Ref {
|
||||
// public:
|
||||
// OffsetRef(
|
||||
// const std::string &name, std::vector<Byte> &v, Size offset, Size bits,
|
||||
// Size ws, bool rel = false, Size ibase = 0
|
||||
// ) : Ref(name, rel, ibase), data(v), offset(offset), bits(bits), wordSize(ws)
|
||||
// {}
|
||||
|
||||
virtual void bind(Addr addr, Addr base = 0) {
|
||||
Size bytes(bits/8), remainder(bits%8);
|
||||
// virtual void bind(Addr addr, Addr base = 0) {
|
||||
// Size bytes(bits/8), remainder(bits%8);
|
||||
|
||||
if (relative) {
|
||||
addr = addr - base;
|
||||
Word_s addr_s(addr);
|
||||
if ((addr_s >> bits) != ~0ull && (addr_s >> bits) != 0) goto noFit;
|
||||
} else {
|
||||
Addr mask = (1ull<<bits)-1;
|
||||
if (addr > mask) goto noFit;
|
||||
}
|
||||
// if (relative) {
|
||||
// addr = addr - base;
|
||||
// Word_s addr_s(addr);
|
||||
// if ((addr_s >> bits) != ~0ull && (addr_s >> bits) != 0) goto noFit;
|
||||
// } else {
|
||||
// Addr mask = (1ull<<bits)-1;
|
||||
// if (addr > mask) goto noFit;
|
||||
// }
|
||||
|
||||
{ Byte mask((1ull<<remainder) - 1);
|
||||
Size i;
|
||||
for (i = 0; i < bytes; i++) {
|
||||
data[offset+i] = addr & 0xff;
|
||||
addr >>= 8;
|
||||
}
|
||||
data[offset+i] &= ~mask;
|
||||
data[offset+i] |= (addr&mask);
|
||||
bound = true;
|
||||
}
|
||||
// { Byte mask((1ull<<remainder) - 1);
|
||||
// Size i;
|
||||
// for (i = 0; i < bytes; i++) {
|
||||
// data[offset+i] = addr & 0xff;
|
||||
// addr >>= 8;
|
||||
// }
|
||||
// data[offset+i] &= ~mask;
|
||||
// data[offset+i] |= (addr&mask);
|
||||
// bound = true;
|
||||
// }
|
||||
|
||||
return;
|
||||
noFit:
|
||||
std::cout << "Attempt to bind a " << bits << "-bit "
|
||||
<< (relative?"":"non-") << "relative symbol to an address"
|
||||
" it cannot reach.\n";
|
||||
exit(1);
|
||||
}
|
||||
// return;
|
||||
// noFit:
|
||||
// std::cout << "Attempt to bind a " << bits << "-bit "
|
||||
// << (relative?"":"non-") << "relative symbol to an address"
|
||||
// " it cannot reach.\n";
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
virtual Addr getAddr() const {
|
||||
Size bytes = bits/8, remainder = bits%8;
|
||||
Byte mask((1<<remainder)-1);
|
||||
Addr a(data[offset]&mask);
|
||||
// virtual Addr getAddr() const {
|
||||
// Size bytes = bits/8, remainder = bits%8;
|
||||
// Byte mask((1<<remainder)-1);
|
||||
// Addr a(data[offset]&mask);
|
||||
|
||||
for (Size i = 0; i < bytes-1; i++) {
|
||||
a |= data[offset + bytes - i - 1];
|
||||
a <<= 8;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
// for (Size i = 0; i < bytes-1; i++) {
|
||||
// a |= data[offset + bytes - i - 1];
|
||||
// a <<= 8;
|
||||
// }
|
||||
// return a;
|
||||
// }
|
||||
|
||||
Size getOffset() const { return offset; }
|
||||
Size getBits() const { return bits; }
|
||||
// Size getOffset() const { return offset; }
|
||||
// Size getBits() const { return bits; }
|
||||
|
||||
private:
|
||||
std::vector<Byte> &data;
|
||||
Size offset, bits, wordSize;
|
||||
};
|
||||
// private:
|
||||
// std::vector<Byte> &data;
|
||||
// Size offset, bits, wordSize;
|
||||
// };
|
||||
|
||||
class Chunk {
|
||||
public:
|
||||
Chunk(std::string n, Size a = 0, Word f = 0) :
|
||||
name(n), alignment(a), bound(false), flags(f), global(false) {}
|
||||
virtual ~Chunk() { for (Size i = 0; i < refs.size(); i++) delete refs[i]; }
|
||||
void bind(Addr a) { address = a; bound = true; }
|
||||
void setGlobal() { global = true; }
|
||||
bool isGlobal() const { return global; }
|
||||
std::string name;
|
||||
Size alignment;
|
||||
bool bound, global;
|
||||
Addr address;
|
||||
Word flags;
|
||||
std::vector<Ref*> refs;
|
||||
};
|
||||
// class Chunk {
|
||||
// public:
|
||||
// Chunk(std::string n, Size a = 0, Word f = 0) :
|
||||
// name(n), alignment(a), bound(false), flags(f), global(false) {}
|
||||
// virtual ~Chunk() { for (Size i = 0; i < refs.size(); i++) delete refs[i]; }
|
||||
// void bind(Addr a) { address = a; bound = true; }
|
||||
// void setGlobal() { global = true; }
|
||||
// bool isGlobal() const { return global; }
|
||||
// std::string name;
|
||||
// Size alignment;
|
||||
// bool bound, global;
|
||||
// Addr address;
|
||||
// Word flags;
|
||||
// std::vector<Ref*> refs;
|
||||
// };
|
||||
|
||||
class TextChunk : public Chunk {
|
||||
public:
|
||||
TextChunk(std::string n, Size a = 0, Word f = 0)
|
||||
: Chunk(n, a, f), instructions() {}
|
||||
// class TextChunk : public Chunk {
|
||||
// public:
|
||||
// TextChunk(std::string n, Size a = 0, Word f = 0)
|
||||
// : Chunk(n, a, f), instructions() {}
|
||||
|
||||
~TextChunk() {
|
||||
for (Size i = 0; i < instructions.size(); i++) delete instructions[i];
|
||||
}
|
||||
// ~TextChunk() {
|
||||
// for (Size i = 0; i < instructions.size(); i++) delete instructions[i];
|
||||
// }
|
||||
|
||||
std::vector<Instruction*> instructions;
|
||||
};
|
||||
// std::vector<Instruction*> instructions;
|
||||
// };
|
||||
|
||||
class DataChunk : public Chunk {
|
||||
public:
|
||||
DataChunk(std::string n, Size a = 0, Word f = 0)
|
||||
: Chunk(n, a, f), size(0), contents() {}
|
||||
Size size;
|
||||
std::vector<Byte> contents; /* 0 to size bytes in length. */
|
||||
};
|
||||
// class DataChunk : public Chunk {
|
||||
// public:
|
||||
// DataChunk(std::string n, Size a = 0, Word f = 0)
|
||||
// : Chunk(n, a, f), size(0), contents() {}
|
||||
// Size size;
|
||||
// std::vector<Byte> contents; /* 0 to size bytes in length. */
|
||||
// };
|
||||
|
||||
class Obj {
|
||||
public:
|
||||
~Obj() { for (Size i = 0; i < chunks.size(); i++) delete chunks[i]; }
|
||||
std::vector<Chunk*> chunks;
|
||||
Size entry;
|
||||
};
|
||||
// class Obj {
|
||||
// public:
|
||||
// ~Obj() { for (Size i = 0; i < chunks.size(); i++) delete chunks[i]; }
|
||||
// std::vector<Chunk*> chunks;
|
||||
// Size entry;
|
||||
// };
|
||||
|
||||
class DynObj : public Obj {
|
||||
public:
|
||||
std::vector<std::string> deps;
|
||||
};
|
||||
// class DynObj : public Obj {
|
||||
// public:
|
||||
// std::vector<std::string> deps;
|
||||
// };
|
||||
|
||||
class ObjReader {
|
||||
public:
|
||||
virtual Obj *read(std::istream &input) = 0;
|
||||
private:
|
||||
};
|
||||
// class ObjReader {
|
||||
// public:
|
||||
// virtual Obj *read(std::istream &input) = 0;
|
||||
// private:
|
||||
// };
|
||||
|
||||
class ObjWriter {
|
||||
public:
|
||||
virtual void write(std::ostream &output, const Obj &o) = 0;
|
||||
private:
|
||||
};
|
||||
// class ObjWriter {
|
||||
// public:
|
||||
// virtual void write(std::ostream &output, const Obj &o) = 0;
|
||||
// private:
|
||||
// };
|
||||
|
||||
class AsmReader : public ObjReader {
|
||||
public:
|
||||
AsmReader(ArchDef arch) :
|
||||
wordSize(arch.getWordSize()), nRegs(arch.getNRegs()) {}
|
||||
virtual Obj *read(std::istream &input);
|
||||
private:
|
||||
Size wordSize, nRegs;
|
||||
// class AsmReader : public ObjReader {
|
||||
// public:
|
||||
// AsmReader(ArchDef arch) :
|
||||
// wordSize(arch.getWordSize()), nRegs(arch.getNRegs()) {}
|
||||
// virtual Obj *read(std::istream &input);
|
||||
// private:
|
||||
// Size wordSize, nRegs;
|
||||
|
||||
// Operand type sequences indexed by argument class
|
||||
enum ArgType {AT_END, AT_REG, AT_PREG, AT_LIT};
|
||||
static ArgType operandtype_table[][4]; // ArgClass -> ArgType[arg_idx]
|
||||
};
|
||||
// // Operand type sequences indexed by argument class
|
||||
// enum ArgType {AT_END, AT_REG, AT_PREG, AT_LIT};
|
||||
// static ArgType operandtype_table[][4]; // ArgClass -> ArgType[arg_idx]
|
||||
// };
|
||||
|
||||
class HOFReader : public ObjReader {
|
||||
public:
|
||||
HOFReader(ArchDef &arch) : arch(arch) {}
|
||||
Obj *read(std::istream &input);
|
||||
private:
|
||||
const ArchDef &arch;
|
||||
};
|
||||
// class HOFReader : public ObjReader {
|
||||
// public:
|
||||
// HOFReader(ArchDef &arch) : arch(arch) {}
|
||||
// Obj *read(std::istream &input);
|
||||
// private:
|
||||
// const ArchDef &arch;
|
||||
// };
|
||||
|
||||
class AsmWriter : public ObjWriter {
|
||||
public:
|
||||
AsmWriter(ArchDef arch): wordSize(arch.getWordSize()) {}
|
||||
virtual void write(std::ostream &output, const Obj &obj);
|
||||
private:
|
||||
Size wordSize;
|
||||
};
|
||||
// class AsmWriter : public ObjWriter {
|
||||
// public:
|
||||
// AsmWriter(ArchDef arch): wordSize(arch.getWordSize()) {}
|
||||
// virtual void write(std::ostream &output, const Obj &obj);
|
||||
// private:
|
||||
// Size wordSize;
|
||||
// };
|
||||
|
||||
class HOFWriter : public ObjWriter {
|
||||
public:
|
||||
HOFWriter(ArchDef &arch) : arch(arch) {}
|
||||
virtual void write(std::ostream &output, const Obj &obj);
|
||||
private:
|
||||
const ArchDef &arch;
|
||||
};
|
||||
};
|
||||
// class HOFWriter : public ObjWriter {
|
||||
// public:
|
||||
// HOFWriter(ArchDef &arch) : arch(arch) {}
|
||||
// virtual void write(std::ostream &output, const Obj &obj);
|
||||
// private:
|
||||
// const ArchDef &arch;
|
||||
// };
|
||||
// };
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user