Checking of assembly input for operand type correctness.

This commit is contained in:
cdkersey 2015-09-29 13:23:57 -06:00
parent 7a2ce3ee37
commit 4840bf3ebd
4 changed files with 45 additions and 4 deletions

View file

@ -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/archdef.h include/args.h include/help.h include/debug.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 \
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
mem.o : mem.cpp include/types.h include/util.h include/mem.h include/debug.h \
include/core.h

View file

@ -1,3 +1,6 @@
#ifndef HARPTOOL_ASM_TOKENS
#define HARPTOOL_ASM_TOKENS
namespace HarpTools {
enum AsmTokens {
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
};
};
#endif

View file

@ -12,7 +12,9 @@
#include "types.h"
#include "archdef.h"
#include "instruction.h"
#include "enc.h"
#include "asm-tokens.h"
namespace Harp {
class Decoder;
@ -174,6 +176,10 @@ namespace Harp {
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]
};
class HOFReader : public ObjReader {

View file

@ -111,6 +111,22 @@ static uint64_t readParenExpression(bool &valid, const string &s,
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;
Obj *AsmReader::read(std::istream &input) {
lexerFloatBytes = wordSize;
@ -146,6 +162,8 @@ Obj *AsmReader::read(std::istream &input) {
Size next_chunk_align(0);
uint64_t num_arg;
RegNum nextPredNum;
Instruction::ArgClass ac;
int argPos;
AsmTokens t;
while ((t = (AsmTokens)f->yylex()) != 0) {
@ -346,7 +364,9 @@ Obj *AsmReader::read(std::istream &input) {
break;
case ASM_T_INST:
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())
asmReaderError(yyline, "Invalid Instruction");
Instruction::Opcode opc = opcIterator->second;
@ -362,14 +382,18 @@ Obj *AsmReader::read(std::istream &input) {
}
curInst = new Instruction();
curInst->setOpcode(opc);
ac = Instruction::instTable[opc].argClass;
argPos = 0;
if (nextPred) {
nextPred = false;
curInst->setPred(nextPredNum);
}
state = Instruction::instTable[opc].allSrcArgs?ST_INST2:ST_INST1;
} else { asmReaderError(yyline, "Unexpected token"); }
} else { asmReaderError(yyline, "Unexpected instruction"); }
break;
case ASM_T_PREG:
if (operandtype_table[ac][argPos++] != AT_PREG)
asmReaderError(yyline, "Unexpected predicate register");
switch (state) {
case ST_INST1: curInst->setDestPReg(yylval.u);
state = ST_INST2;
@ -394,6 +418,8 @@ Obj *AsmReader::read(std::istream &input) {
case ASM_T_REG:
continue_reg:
if (operandtype_table[ac][argPos++] != AT_REG)
asmReaderError(yyline, "Unexpected register operand.");
switch (state) {
case ST_INST1: curInst->setDestReg(yylval.u);
state = ST_INST2;
@ -410,6 +436,8 @@ Obj *AsmReader::read(std::istream &input) {
if (!valid) asmReaderError(yyline, "Invalid paren expression");
}
case ASM_T_LIT:
if (operandtype_table[ac][argPos++] != AT_LIT)
asmReaderError(yyline, "Unexpected literal operand.");
switch (state) {
case ST_INST1: asmReaderError(yyline, "Unexpected literal");
case ST_INST2: curInst->setSrcImm(yylval.u);
@ -418,6 +446,8 @@ Obj *AsmReader::read(std::istream &input) {
}
break;
case ASM_T_SYM:
if (operandtype_table[ac][argPos++] != AT_LIT)
asmReaderError(yyline, "Unexpected symbol operand.");
switch (state) {
case ST_INST1: asmReaderError(yyline, "Unexpected symbol");
case ST_INST2: if (defs.find(yylval.s) != defs.end()) {