diff options
-rw-r--r-- | assemble.c | 51 | ||||
-rw-r--r-- | opcode.h | 27 | ||||
-rw-r--r-- | sux.c | 23 | ||||
-rw-r--r-- | sux.h | 51 |
4 files changed, 59 insertions, 93 deletions
@@ -25,10 +25,9 @@ uint8_t get_rs(token *t, uint8_t inst, uint8_t dbg) { uint64_t get_val(token *t, uint64_t addr, uint8_t size, uint8_t dbg) { uint64_t value = 0; uint64_t tmp_val = 0; - uint16_t expr_count = 0; uint8_t type = EXPR_NONE; do { - if (expr_count) { + if (t->id == TOK_EXPR) { type = t->type; t = t->next; } @@ -36,15 +35,9 @@ uint64_t get_val(token *t, uint64_t addr, uint8_t size, uint8_t dbg) { case TOK_HEX: case TOK_DEC: case TOK_BIN: - case TOK_CHAR: - tmp_val = t->qword; - t = t->next; - break; + case TOK_CHAR: tmp_val = t->qword; t = t->next; break; case TOK_SYM: - case TOK_LABEL: - tmp_val = (t->sym) ? t->sym->val : addr; - t = t->next; - break; + case TOK_LABEL: tmp_val = (t->sym) ? t->sym->val : addr; t = t-> next; break; } switch (type) { case EXPR_PLUS : value += tmp_val; break; @@ -67,11 +60,7 @@ uint64_t get_val(token *t, uint64_t addr, uint8_t size, uint8_t dbg) { break; case EXPR_NONE : value = tmp_val; break; } - expr_count++; - if (!t) { - break; - } - } while (t->id == TOK_EXPR && isexpr(t->type, dbg)); + } while (t && t->id == TOK_EXPR && isexpr(t->type, dbg)); return value; } @@ -186,7 +175,7 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, break; } tmp = 0; - opsize = 0; + opsize = 1; opcode = 0; if (t->next) { rs = get_rs(t->next, inst, dbg); @@ -231,35 +220,13 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, } address++; bc->progsize++; - switch (rs) { - case 3: - if (isasm) { - addr[address+7] = val.u8[7]; - addr[address+6] = val.u8[6]; - addr[address+5] = val.u8[5]; - addr[address+4] = val.u8[4]; - } - tmp += 4; - case 2: - if (isasm) { - addr[address+3] = val.u8[3]; - addr[address+2] = val.u8[2]; - } - tmp += 2; - case 1 : - if (isasm) { - addr[address+1] = val.u8[1]; - } - tmp++; - default: - if (isasm) { - addr[address ] = val.u8[0]; - } - tmp++; + rs = (rs != 0xFF) ? rs : 0; + tmp = (1 << rs); + if (isasm) { + setreg(addr, +, address, val.u8, +, 0, tmp-1); } break; default: - opsize = (val.u64 <= 0x00000000000000FF) ? 1 : opsize; opsize = (val.u64 > 0x00000000000000FF) ? 2 : opsize; opsize = (val.u64 > 0x000000000000FFFF) ? 3 : opsize; opsize = (val.u64 > 0x0000000000FFFFFF) ? 4 : opsize; @@ -18,6 +18,31 @@ #define V (1 << 6) /* oVerflow flag. */ #define N (1 << 7) /* Negative flag. */ +extern uint8_t get_addrsize(uint8_t prefix, uint8_t addrmode); + +/* reg_expr, and val_expr are the arithmetic expressions + * that will be used for either the value, or register, such as '+', or '-'. + */ +#define setreg(reg, reg_expr, reg_idx, val, val_expr, val_idx, size) {\ + switch (size) {\ + case 7: reg[(reg_idx) reg_expr 7] = val[(val_idx) val_expr 7];\ + case 6: reg[(reg_idx) reg_expr 6] = val[(val_idx) val_expr 6];\ + case 5: reg[(reg_idx) reg_expr 5] = val[(val_idx) val_expr 5];\ + case 4: reg[(reg_idx) reg_expr 4] = val[(val_idx) val_expr 4];\ + case 3: reg[(reg_idx) reg_expr 3] = val[(val_idx) val_expr 3];\ + case 2: reg[(reg_idx) reg_expr 2] = val[(val_idx) val_expr 2];\ + case 1: reg[(reg_idx) reg_expr 1] = val[(val_idx) val_expr 1];\ + case 0: reg[(reg_idx) reg_expr 0] = val[(val_idx) val_expr 0];\ + }\ +} + +#define setreg_sw(reg, reg_idx, val, val_idx, prefix, addrmode, type) {\ + switch (type) {\ + case RS: setreg(reg, +, reg_idx, val, +, val_idx, (1 << (prefix >> 4))-1); break;\ + case AM: setreg(reg, +, reg_idx, val, +, val_idx, get_addrsize(prefix, addrmode)); break;\ + }\ +} + extern uint8_t *addr; /* Address Space. */ union reg { @@ -37,3 +62,5 @@ struct sux { }; extern int asmmon(); + +enum sw_type {RS, AM, BYTE}; @@ -47,6 +47,29 @@ double ipc; struct timeval str[THREADS], en[THREADS]; #endif +inline uint8_t get_addrsize(uint8_t prefix, uint8_t addrmode) { + uint8_t id = (prefix & 0x0C) >> 2; + switch (addrmode) { + case ZM: + switch (id) { + case 2: return 5; + case 3: return 3; + case 1: return 2; + case 0: return 0; + } + break; + case ABS: + switch (id) { + case 3: return 7; + case 2: return 6; + case 1: return 4; + case 0: return 1; + } + break; + } + return 0; +} + void *run(void *args) { struct suxthr *thr = (void *)args; struct sux *cpu = &thr->sx; @@ -25,37 +25,9 @@ extern uint8_t subdbg; extern uint8_t step; extern uint8_t esc; -static inline uint8_t get_addrsize(uint8_t prefix, uint8_t addrmode); - -enum sw_type {RS, AM, BYTE}; - #define setflag(flag, bit) ((flag)) ? (cpu->ps.u8[thread] |= bit) : (cpu->ps.u8[thread] &= ~bit) #define getflag(bit) (cpu->ps.u8[thread] & bit) -/* reg_expr, and val_expr are the arithmetic expressions - * that will be used for either the value, or register, such as '+', or '-'. - */ -#define setreg(reg, reg_expr, reg_idx, val, val_expr, val_idx, size) {\ - switch (size) {\ - case 7: reg[(reg_idx) reg_expr 7] = val[(val_idx) val_expr 7];\ - case 6: reg[(reg_idx) reg_expr 6] = val[(val_idx) val_expr 6];\ - case 5: reg[(reg_idx) reg_expr 5] = val[(val_idx) val_expr 5];\ - case 4: reg[(reg_idx) reg_expr 4] = val[(val_idx) val_expr 4];\ - case 3: reg[(reg_idx) reg_expr 3] = val[(val_idx) val_expr 3];\ - case 2: reg[(reg_idx) reg_expr 2] = val[(val_idx) val_expr 2];\ - case 1: reg[(reg_idx) reg_expr 1] = val[(val_idx) val_expr 1];\ - case 0: reg[(reg_idx) reg_expr 0] = val[(val_idx) val_expr 0];\ - }\ -} - -#define setreg_sw(reg, reg_idx, val, val_idx, prefix, addrmode, type) {\ - switch (type) {\ - case RS: setreg(reg, +, reg_idx, val, +, val_idx, (1 << (prefix >> 4))-1); break;\ - case AM: setreg(reg, +, reg_idx, val, +, val_idx, get_addrsize(prefix, addrmode)); break;\ - }\ -} - - extern pthread_mutex_t mutex; extern pthread_mutex_t main_mutex; extern pthread_cond_t cond; @@ -67,29 +39,6 @@ extern void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t o extern void io(uint64_t address, uint8_t rw); -static inline uint8_t get_addrsize(uint8_t prefix, uint8_t addrmode) { - uint8_t id = (prefix & 0x0C) >> 2; - switch (addrmode) { - case ZM: - switch (id) { - case 2: return 5; - case 3: return 3; - case 1: return 2; - case 0: return 0; - } - break; - case ABS: - switch (id) { - case 3: return 7; - case 2: return 6; - case 1: return 4; - case 0: return 1; - } - break; - } - return 0; -} - static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opcode, uint8_t prefix, uint8_t thread) { union reg address; union reg value; |