Checking of assembly input for operand type correctness.
This commit is contained in:
@@ -27,9 +27,9 @@ harptool.o : harptool.cpp include/types.h include/core.h include/enc.h \
|
|||||||
include/instruction.h include/mem.h include/obj.h \
|
include/instruction.h include/mem.h include/obj.h \
|
||||||
include/archdef.h include/args.h include/help.h include/debug.h
|
include/archdef.h include/args.h include/help.h include/debug.h
|
||||||
instruction.o : instruction.cpp include/instruction.h include/obj.h \
|
instruction.o : instruction.cpp include/instruction.h include/obj.h \
|
||||||
include/core.h include/debug.h
|
include/core.h include/debug.h include/asm-tokens.h
|
||||||
obj.o : obj.cpp include/types.h include/obj.h include/util.h \
|
obj.o : obj.cpp include/types.h include/obj.h include/util.h \
|
||||||
include/asm-tokens.h include/debug.h
|
include/asm-tokens.h include/debug.h include/instruction.h
|
||||||
util.o : util.cpp include/types.h include/util.h
|
util.o : util.cpp include/types.h include/util.h
|
||||||
mem.o : mem.cpp include/types.h include/util.h include/mem.h include/debug.h \
|
mem.o : mem.cpp include/types.h include/util.h include/mem.h include/debug.h \
|
||||||
include/core.h
|
include/core.h
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
#ifndef HARPTOOL_ASM_TOKENS
|
||||||
|
#define HARPTOOL_ASM_TOKENS
|
||||||
|
|
||||||
namespace HarpTools {
|
namespace HarpTools {
|
||||||
enum AsmTokens {
|
enum AsmTokens {
|
||||||
ASM_T_DIR_DEF = 1, ASM_T_DIR_PERM, ASM_T_DIR_BYTE, ASM_T_DIR_WORD,
|
ASM_T_DIR_DEF = 1, ASM_T_DIR_PERM, ASM_T_DIR_BYTE, ASM_T_DIR_WORD,
|
||||||
@@ -9,3 +12,5 @@ namespace HarpTools {
|
|||||||
ASM_T_REG_FP, ASM_T_LIT, ASM_T_SYM, ASM_T_PEXP
|
ASM_T_REG_FP, ASM_T_LIT, ASM_T_SYM, ASM_T_PEXP
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "archdef.h"
|
#include "archdef.h"
|
||||||
|
#include "instruction.h"
|
||||||
#include "enc.h"
|
#include "enc.h"
|
||||||
|
#include "asm-tokens.h"
|
||||||
|
|
||||||
namespace Harp {
|
namespace Harp {
|
||||||
class Decoder;
|
class Decoder;
|
||||||
@@ -174,6 +176,10 @@ namespace Harp {
|
|||||||
virtual Obj *read(std::istream &input);
|
virtual Obj *read(std::istream &input);
|
||||||
private:
|
private:
|
||||||
Size wordSize, nRegs;
|
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]
|
||||||
};
|
};
|
||||||
|
|
||||||
class HOFReader : public ObjReader {
|
class HOFReader : public ObjReader {
|
||||||
|
|||||||
34
src/obj.cpp
34
src/obj.cpp
@@ -111,6 +111,22 @@ static uint64_t readParenExpression(bool &valid, const string &s,
|
|||||||
return rPE(valid, s, d, 0, s.length());
|
return rPE(valid, s, d, 0, s.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AsmReader::ArgType AsmReader::operandtype_table[][4] = {
|
||||||
|
{AT_END}, // AC_NONE
|
||||||
|
{AT_REG, AT_REG, AT_END}, // AC_2REG
|
||||||
|
{AT_REG, AT_LIT, AT_END}, // AC_2IMM
|
||||||
|
{AT_REG, AT_REG, AT_REG, AT_END}, // AC_3REG
|
||||||
|
{AT_PREG, AT_PREG, AT_PREG, AT_END}, // AC_3PREG
|
||||||
|
{AT_REG, AT_REG, AT_LIT, AT_END}, // AC_3IMM
|
||||||
|
{AT_REG, AT_REG, AT_REG, AT_END}, // AC_3REGSRC
|
||||||
|
{AT_LIT, AT_END}, // AC_1IMM
|
||||||
|
{AT_REG, AT_END}, // AC_1REG
|
||||||
|
{AT_REG, AT_REG, AT_LIT, AT_END}, // AC_3IMMSRC
|
||||||
|
{AT_PREG, AT_REG, AT_END}, // AC_PREG_REG
|
||||||
|
{AT_PREG, AT_PREG, AT_END}, // AC_2PREG
|
||||||
|
{AT_REG, AT_REG, AT_END} // AC_2REGSRC
|
||||||
|
};
|
||||||
|
|
||||||
int lexerFloatBytes;
|
int lexerFloatBytes;
|
||||||
Obj *AsmReader::read(std::istream &input) {
|
Obj *AsmReader::read(std::istream &input) {
|
||||||
lexerFloatBytes = wordSize;
|
lexerFloatBytes = wordSize;
|
||||||
@@ -146,6 +162,8 @@ Obj *AsmReader::read(std::istream &input) {
|
|||||||
Size next_chunk_align(0);
|
Size next_chunk_align(0);
|
||||||
uint64_t num_arg;
|
uint64_t num_arg;
|
||||||
RegNum nextPredNum;
|
RegNum nextPredNum;
|
||||||
|
Instruction::ArgClass ac;
|
||||||
|
int argPos;
|
||||||
|
|
||||||
AsmTokens t;
|
AsmTokens t;
|
||||||
while ((t = (AsmTokens)f->yylex()) != 0) {
|
while ((t = (AsmTokens)f->yylex()) != 0) {
|
||||||
@@ -346,7 +364,9 @@ Obj *AsmReader::read(std::istream &input) {
|
|||||||
break;
|
break;
|
||||||
case ASM_T_INST:
|
case ASM_T_INST:
|
||||||
if (state == ST_INIT) {
|
if (state == ST_INIT) {
|
||||||
map<string, Instruction::Opcode>::iterator opcIterator = opMap.find(yylval.s);
|
map<string, Instruction::Opcode>::iterator
|
||||||
|
opcIterator = opMap.find(yylval.s);
|
||||||
|
|
||||||
if (opcIterator == opMap.end())
|
if (opcIterator == opMap.end())
|
||||||
asmReaderError(yyline, "Invalid Instruction");
|
asmReaderError(yyline, "Invalid Instruction");
|
||||||
Instruction::Opcode opc = opcIterator->second;
|
Instruction::Opcode opc = opcIterator->second;
|
||||||
@@ -362,14 +382,18 @@ Obj *AsmReader::read(std::istream &input) {
|
|||||||
}
|
}
|
||||||
curInst = new Instruction();
|
curInst = new Instruction();
|
||||||
curInst->setOpcode(opc);
|
curInst->setOpcode(opc);
|
||||||
|
ac = Instruction::instTable[opc].argClass;
|
||||||
|
argPos = 0;
|
||||||
if (nextPred) {
|
if (nextPred) {
|
||||||
nextPred = false;
|
nextPred = false;
|
||||||
curInst->setPred(nextPredNum);
|
curInst->setPred(nextPredNum);
|
||||||
}
|
}
|
||||||
state = Instruction::instTable[opc].allSrcArgs?ST_INST2:ST_INST1;
|
state = Instruction::instTable[opc].allSrcArgs?ST_INST2:ST_INST1;
|
||||||
} else { asmReaderError(yyline, "Unexpected token"); }
|
} else { asmReaderError(yyline, "Unexpected instruction"); }
|
||||||
break;
|
break;
|
||||||
case ASM_T_PREG:
|
case ASM_T_PREG:
|
||||||
|
if (operandtype_table[ac][argPos++] != AT_PREG)
|
||||||
|
asmReaderError(yyline, "Unexpected predicate register");
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case ST_INST1: curInst->setDestPReg(yylval.u);
|
case ST_INST1: curInst->setDestPReg(yylval.u);
|
||||||
state = ST_INST2;
|
state = ST_INST2;
|
||||||
@@ -394,6 +418,8 @@ Obj *AsmReader::read(std::istream &input) {
|
|||||||
|
|
||||||
case ASM_T_REG:
|
case ASM_T_REG:
|
||||||
continue_reg:
|
continue_reg:
|
||||||
|
if (operandtype_table[ac][argPos++] != AT_REG)
|
||||||
|
asmReaderError(yyline, "Unexpected register operand.");
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case ST_INST1: curInst->setDestReg(yylval.u);
|
case ST_INST1: curInst->setDestReg(yylval.u);
|
||||||
state = ST_INST2;
|
state = ST_INST2;
|
||||||
@@ -410,6 +436,8 @@ Obj *AsmReader::read(std::istream &input) {
|
|||||||
if (!valid) asmReaderError(yyline, "Invalid paren expression");
|
if (!valid) asmReaderError(yyline, "Invalid paren expression");
|
||||||
}
|
}
|
||||||
case ASM_T_LIT:
|
case ASM_T_LIT:
|
||||||
|
if (operandtype_table[ac][argPos++] != AT_LIT)
|
||||||
|
asmReaderError(yyline, "Unexpected literal operand.");
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case ST_INST1: asmReaderError(yyline, "Unexpected literal");
|
case ST_INST1: asmReaderError(yyline, "Unexpected literal");
|
||||||
case ST_INST2: curInst->setSrcImm(yylval.u);
|
case ST_INST2: curInst->setSrcImm(yylval.u);
|
||||||
@@ -418,6 +446,8 @@ Obj *AsmReader::read(std::istream &input) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASM_T_SYM:
|
case ASM_T_SYM:
|
||||||
|
if (operandtype_table[ac][argPos++] != AT_LIT)
|
||||||
|
asmReaderError(yyline, "Unexpected symbol operand.");
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case ST_INST1: asmReaderError(yyline, "Unexpected symbol");
|
case ST_INST1: asmReaderError(yyline, "Unexpected symbol");
|
||||||
case ST_INST2: if (defs.find(yylval.s) != defs.end()) {
|
case ST_INST2: if (defs.find(yylval.s) != defs.end()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user