summaryrefslogtreecommitdiff
path: root/output.c
diff options
context:
space:
mode:
authorDavid Phillips <david@sighup.nz>2019-08-03 14:44:12 +1200
committerDavid Phillips <david@sighup.nz>2019-08-03 14:47:14 +1200
commit22575e056586a7810007952c717eff4e9e005bdb (patch)
tree92b7407994b7e183f4723ed80641bb75a6f2ca32 /output.c
parent085145a1f49ffcae235fa559df254919366fe497 (diff)
downloadtoy-cpu-assembler-22575e056586a7810007952c717eff4e9e005bdb.tar.xz
File input and output routines away
Diffstat (limited to 'output.c')
-rw-r--r--output.c200
1 files changed, 0 insertions, 200 deletions
diff --git a/output.c b/output.c
deleted file mode 100644
index d536b7e..0000000
--- a/output.c
+++ /dev/null
@@ -1,200 +0,0 @@
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "parse.h"
-
-static size_t cur_byte;
-
-int generate_single_r_type(uint32_t *dest, struct r_type inst)
-{
- uint32_t i = 0;
-
- i |= MASK_INST_RTYPE;
- i |= MASK_OPER(inst.oper);
- i |= MASK_REG_DEST(inst.dest);
- i |= MASK_REG_LEFT(inst.left);
- i |= MASK_REG_RIGHT(inst.right);
-
- *dest = i;
- return 1;
-}
-int generate_single_ni_type(uint32_t *dest, struct i_type inst)
-{
- uint32_t i = 0;
-
- i |= MASK_INST_NITYPE;
- i |= MASK_OPER(inst.oper);
- i |= MASK_REG_DEST(inst.dest);
- i |= MASK_REG_LEFT(inst.left);
- i |= MASK_NI_IMM(inst.imm.value);
-
- *dest = i;
- return 1;
-}
-
-int generate_single_wi_type(uint32_t *dest, struct i_type inst)
-{
- uint32_t i = 0;
-
- i |= MASK_INST_WITYPE;
- i |= MASK_OPER(inst.oper);
- i |= MASK_REG_DEST(inst.dest);
- i |= MASK_REG_LEFT(inst.left);
-
- /* two-word instruction - make room for the immediate */
- i <<= 16;
-
- i |= inst.imm.value;
-
- *dest = i;
- return 2;
-}
-
-int generate_single_ji_type(uint32_t *dest, struct ji_type inst)
-{
- uint32_t i = 0;
-
- i |= MASK_INST_JTYPE;
- i |= MASK_IS_JUMP;
- i |= MASK_JB_COND(inst.cond);
- i |= MASK_JI;
-
- /* two-word instruction - make room for the immediate */
- i <<= 16;
-
- i |= inst.imm.value;
-
- *dest = i;
- return 2;
-}
-
-int generate_single_jr_type(uint32_t *dest, struct jr_type inst)
-{
- uint32_t i = 0;
-
- i |= MASK_INST_JTYPE;
- i |= MASK_IS_JUMP;
- i |= MASK_JB_COND(inst.cond);
- i |= MASK_JR;
- i |= MASK_JUMP_REGISTER(inst.reg);
-
- *dest = i;
- return 1;
-}
-
-int generate_single_b_type(uint32_t *dest, struct b_type inst)
-{
- uint32_t i = 0;
-
- i |= MASK_INST_JTYPE;
- i |= MASK_IS_BRANCH;
- i |= MASK_JB_COND(inst.cond);
- i |= MASK_B_OFFSET(inst.imm.value);
-
- *dest = i;
- return 1;
-}
-
-
-int look_up_label(struct label *labels, size_t labels_count, uint16_t *val, const char *label)
-{
- size_t i = 0;
-
- for (i = 0; i < labels_count; i++) {
- if (strcmp(labels[i].name, label) == 0) {
- *val = labels[i].byte_offset;
- return 0;
- }
- }
-
- /* FIXME emit */
- fprintf(stderr, "Reference to undefined label `%s'\n", label);
- return 1;
-}
-
-int output_single(FILE *f, struct label *labels, size_t labels_count, struct instruction inst)
-{
- int len = 0;
- uint32_t i = 0;
-
- switch (inst.type) {
- case INST_TYPE_R:
- len = generate_single_r_type(&i, inst.inst.r);
- break;
- case INST_TYPE_NI:
- if ( inst.inst.i.imm_is_ident
- && look_up_label(labels, labels_count, &inst.inst.i.imm.value, inst.inst.i.imm.label))
- return 1;
-
- len = generate_single_ni_type(&i, inst.inst.i);
- break;
- case INST_TYPE_WI:
- if ( inst.inst.i.imm_is_ident
- && look_up_label(labels, labels_count, &inst.inst.i.imm.value, inst.inst.i.imm.label))
- return 1;
-
- len = generate_single_wi_type(&i, inst.inst.i);
- break;
- case INST_TYPE_JR:
- len = generate_single_jr_type(&i, inst.inst.jr);
- break;
- case INST_TYPE_JI:
- if ( inst.inst.ji.imm_is_ident
- && look_up_label(labels, labels_count, &inst.inst.ji.imm.value, inst.inst.ji.imm.label))
- return 1;
-
- len = generate_single_ji_type(&i, inst.inst.ji);
- break;
- case INST_TYPE_B:
- if ( inst.inst.b.imm_is_ident
- && look_up_label(labels, labels_count, &inst.inst.b.imm.value, inst.inst.b.imm.label))
- return 1;
- inst.inst.b.imm.value -= cur_byte;
- if (inst.inst.b.imm.value % 2 != 0) {
- fprintf(stderr, "Internal error: branch offset %d not a multiple of 2\n", inst.inst.b.imm.value);
- }
- inst.inst.b.imm.value /= 2;
-
- len = generate_single_b_type(&i, inst.inst.b);
- break;
- default:
- fprintf(stderr, "Internal error: unhandled instruction type\n");
- break;
- }
-
- if (len == 2) {
-#define RAW
-#ifdef RAW
- fputc(0xFF & (i >> 24), f);
- fputc(0xFF & (i >> 16), f);
-#else
- fprintf(f, "%04x ", i >> 16);
-#endif
- }
-#ifdef RAW
- fputc(0xFF & (i >> 8), f);
- fputc(0xFF & (i >> 0), f);
-#else
- fprintf(f, "%04x ", 0xFFFF & i);
-#endif
-
- cur_byte += 2 * len;
- return 0;
-}
-
-int output(FILE *fout, struct label *labels, size_t label_count, struct instruction *insts, size_t insts_count)
-{
- size_t i = 0;
- cur_byte = 0;
-
-#ifndef RAW
- fprintf(fout, "v2.0 raw\n");
-#endif
-
- for (i = 0; i < insts_count; i++)
- if (output_single(fout, labels, label_count, insts[i]))
- return 1;
-
- return 0;
-}