blob: 241cf3e70dc6a863abb313da71536afa107ea3dc [file] [log] [blame]
/* %%%%%%%%%%%%%%%%%%%% (c) William Landi 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%% */
/* Permission to use this code is granted as long as the copyright */
/* notice remains in place. */
/* ============================== op_tab =================================== */
/* Defines and allows for loop up in the OPERATOR TABLE */
#include <stdio.h>
#include <string.h>
#include "pseudo.h"
/* ---------------- Possible formats for instructions. */
enum formats {ONE,TWO,THREE_FOUR,PSEUDO,NOT_FOUND};
/* ---------------- Possible operand types --------------------------------- */
enum operands
{NONE,REG,REG_REG,MEM,REG_NUM,NUM,PSEUDO_LOC,PSEUDO_NOLOC,PSEUDO_ADDR};
/* ---------------- Structure of the operator table */
struct OP_ENTRY {
char *MNEMONIC; /* Name of the operator */
enum formats FORMAT; /* FORMAT of this operator */
char *OPCODE; /* OPCODE for this operator */
enum operands OPERAND; /* Number and type of operands */
int FUNCTION; /* Function to execute is PASS1. Pseudo */
/* operators only. */
};
#define NUM_OPCODES 59 /* number of opcodes in the table */
/* NOT counting the NOT_FOUND entry */
/* table (sorted array) of keywords used in EMITID */
struct OP_ENTRY OP_TABLE[] =
{{"ADD",THREE_FOUR,"18",MEM,NULL},
{"ADDR",TWO,"90",REG_REG,NULL},
{"AND",THREE_FOUR,"40",MEM,NULL},
{"BYTE",PSEUDO," ",PSEUDO_LOC,PSEUDO_BYTE0},
{"CLEAR",TWO,"B4",REG,NULL},
{"COMP",THREE_FOUR,"28",MEM,NULL},
{"COMPR",TWO,"A0",REG_REG,NULL},
{"CSECT",PSEUDO," ",PSEUDO_ADDR,PSEUDO_CSECT0},
{"DIV",THREE_FOUR,"24",MEM,NULL}, {"DIVR",TWO,"9C",REG_REG,NULL},
{"END",PSEUDO," ",PSEUDO_LOC,PSEUDO_END0},
{"EQU",PSEUDO," ",PSEUDO_ADDR,PSEUDO_EQU0},
{"EXTDEF",PSEUDO," ",PSEUDO_NOLOC,PSEUDO_EXTDEF0},
{"EXTREF",PSEUDO," ",PSEUDO_NOLOC,PSEUDO_EXTREF0},
{"HIO",ONE,"F4",NONE,NULL}, {"J",THREE_FOUR,"3C",MEM,NULL},
{"JEQ",THREE_FOUR,"30",MEM,NULL}, {"JGT",THREE_FOUR,"34",MEM,NULL},
{"JLT",THREE_FOUR,"38",MEM,NULL}, {"JSUB",THREE_FOUR,"48",MEM,NULL},
{"LDA",THREE_FOUR,"00",MEM,NULL}, {"LDB",THREE_FOUR,"68",MEM,NULL},
{"LDCH",THREE_FOUR,"50",MEM,NULL}, {"LDL",THREE_FOUR,"08",MEM,NULL},
{"LDS",THREE_FOUR,"6C",MEM,NULL}, {"LDT",THREE_FOUR,"74",MEM,NULL},
{"LDX",THREE_FOUR,"04",MEM,NULL}, {"LPS",THREE_FOUR,"D0",MEM,NULL},
{"MUL",THREE_FOUR,"20",MEM,NULL}, {"MULR",TWO,"98",REG_REG,NULL},
{"OR",THREE_FOUR,"44",MEM,NULL}, {"RD",THREE_FOUR,"D8",MEM,NULL},
{"RESB",PSEUDO," ",PSEUDO_LOC,PSEUDO_RESB0},
{"RESW",PSEUDO," ",PSEUDO_LOC,PSEUDO_RESW0},
{"RMO",TWO,"AC",REG_REG,NULL}, {"RSUB",THREE_FOUR,"4C",NONE,NULL},
{"SHIFTL",TWO,"A4",REG_NUM,NULL}, {"SHIFTR",TWO,"A8",REG_NUM,NULL},
{"SIO",ONE,"F0",NONE,NULL}, {"SSK",THREE_FOUR,"EC",MEM,NULL},
{"STA",THREE_FOUR,"0C",MEM,NULL},
{"START",PSEUDO," ",PSEUDO_ADDR,PSEUDO_START0},
{"STB",THREE_FOUR,"78",MEM,NULL}, {"STCH",THREE_FOUR,"54",MEM,NULL},
{"STI",THREE_FOUR,"D4",MEM,NULL}, {"STL",THREE_FOUR,"14",MEM,NULL},
{"STS",THREE_FOUR,"7C",MEM,NULL}, {"STSW",THREE_FOUR,"E8",MEM,NULL},
{"STT",THREE_FOUR,"84",MEM,NULL}, {"STX",THREE_FOUR,"10",MEM,NULL},
{"SUB",THREE_FOUR,"1C",MEM,NULL}, {"SUBR",TWO,"94",REG_REG,NULL},
{"SVC",TWO,"B0",NUM,NULL}, {"TD",THREE_FOUR,"E0",MEM,NULL},
{"TIO",ONE,"F8",NONE,NULL}, {"TIX",THREE_FOUR,"2C",MEM,NULL},
{"TIXR",TWO,"B8",REG,NULL}, {"WD",THREE_FOUR,"DC",MEM,NULL},
{"WORD",PSEUDO," ",PSEUDO_LOC,PSEUDO_WORD0},
/* the next entry must always be last */
{"*END OF TABLE*",NOT_FOUND,"00",NONE,NULL}};
/* ---------------------------- LOOK_UP_OP --------------------------------- */
/* Find operator in the table. Return the entry if it is found, else return */
/* the not found entry. Uses BINARY SEARCH. */
struct OP_ENTRY *LOOK_UP_OP(char OP[])
{
int LOW = 0, /* LOWest element in OP_TABLE that may be the OP */
HIGH = NUM_OPCODES-1,/* HIGHest element that may be the OP */
MIDDLE; /* (LOW+HIGH)/2... next element considering */
int CMP; /* stores the result of a string comparison; */
/* 0 str1 = str2, 1 str1 > str2, -1 str1 < str2 */
MIDDLE = 0;
while (LOW <= HIGH)
{
MIDDLE = (HIGH + LOW)/2;
if (!(CMP = strcmp(OP_TABLE[MIDDLE].MNEMONIC,OP)))
return &OP_TABLE[MIDDLE];
if (CMP > 0)
HIGH = MIDDLE - 1;
else LOW = MIDDLE + 1;
}
return &OP_TABLE[NUM_OPCODES];
}