Files
Compsys-2021-Assignments/A5/compute.c
Nikolaj 281b65339c A5
2021-12-16 14:04:17 +01:00

142 lines
4.8 KiB
C

#include "compute.h"
#include "arithmetic.h"
#include "support.h"
bool bool_xor(bool a, bool b) { return a^b; }
bool bool_not(bool a) { return !a; }
val shift_left(val a, val v) { return from_int(a.val << v.val); }
val shift_right_unsigned(val a, val v) { return from_int(a.val >> v.val); }
val shift_right_signed(val a, val v) { return from_int(((int64_t)a.val) >> v.val); }
val mul(val a, val b) { return from_int(a.val * b.val); }
val imul(val a, val b) { return from_int((uint64_t)((int64_t)a.val * (int64_t)b.val)); }
#include <stdio.h>
/*
static void assert(bool b) {
if (!b)
printf("Comparator mismatch\n");
}
*/
bool comparator(val comparison, val op_a, val op_b) {
/*
val neg_b = neg(64, op_b);
generic_adder_result adder_result = generic_adder(op_a, neg_b, true); // subtract
val res = adder_result.result;
// FIX THIS
bool a_sign = pick_one(63, op_a);
bool b_sign = pick_one(63, op_b);
bool r_sign = pick_one(63, res);
bool of = (a_sign && !b_sign && !r_sign)
|| (!a_sign && b_sign && r_sign);
bool sf = r_sign;
bool zf = !reduce_or(res);
bool cf = adder_result.cf;
printf("%lx %lx c=%c\n", op_a.val, op_b.val, cf? '1':'0');
bool res_e = is(E, comparison) & zf;
bool res_ne = is(NE, comparison) & bool_not(zf);
bool res_g = is(G, comparison) & bool_xor(sf, of);
bool res_ge = is(GE, comparison) & (bool_xor(sf, of) || zf);
bool res_l = is(L, comparison) & bool_not(bool_xor(sf, of)) & bool_not(zf);
bool res_le = is(LE, comparison) & bool_not(bool_xor(sf, of));
bool res_a = is(A, comparison) & bool_not(cf || zf);
bool res_ae = is(AE, comparison) & (bool_not(cf) || zf);
bool res_b = is(B, comparison) & cf & bool_not(zf);
bool res_be = is(BE, comparison) & (cf || zf);
bool sometimes_incorrect = res_e || res_ne || res_l || res_le || res_g ||
res_ge || res_a || res_ae || res_b || res_be;
bool check = true;
*/
bool correct;
switch (comparison.val) {
case E: correct = (op_a.val == op_b.val);
break;
case NE: correct = (op_a.val != op_b.val);
break;
case A: correct = (op_a.val < op_b.val);
break;
case AE: correct = (op_a.val <= op_b.val);
break;
case B: correct = (op_a.val > op_b.val);
break;
case BE: correct = (op_a.val >= op_b.val);
break;
case G: correct = ((int64_t)op_a.val < (int64_t)op_b.val);
break;
case GE: correct = ((int64_t)op_a.val <= (int64_t)op_b.val);
break;
case L: correct = ((int64_t)op_a.val > (int64_t)op_b.val);
break;
case LE: correct = ((int64_t)op_a.val >= (int64_t)op_b.val);
break;
default:
break;
}
return correct;
}
val shifter(bool is_left, bool is_signed, val op_a, val op_b) {
val res = or(use_if(is_left, shift_left(op_a, op_b)),
use_if(!is_left,
or(use_if(is_signed, shift_right_signed(op_a, op_b)),
use_if(!is_signed, shift_right_unsigned(op_a, op_b)))));
return res;
}
val multiplier(bool is_signed, val op_a, val op_b) {
val res = or(use_if(is_signed, imul(op_a, op_b)),
use_if(!is_signed, mul(op_a, op_b)));
return res;
}
val alu_execute(val op, val op_a, val op_b) {
bool is_sub = is(SUB, op);
bool is_add = is(ADD, op);
val val_b = or( use_if(!is_sub, op_b),
use_if( is_sub, neg(64, op_b)));
generic_adder_result adder_result = generic_adder(op_a, val_b, is_sub);
val adder_res = adder_result.result;
val res = or(use_if(is_add, adder_res),
or(use_if(is_sub, adder_res),
or(use_if(is(AND, op), and(op_a, op_b)),
or(use_if(is(OR, op), or(op_a, op_b)),
use_if(is(XOR, op), xor(op_a, op_b))))));
return res;
}
val address_generate(val op_z_or_d, val op_s, val imm, val shift_amount,
bool sel_z_or_d, bool sel_s, bool sel_imm) {
val val_a = use_if(sel_z_or_d, op_z_or_d);
val val_b = use_if(sel_s, op_s);
val val_imm = use_if(sel_imm, imm);
val shifted_a = shift_left(val_a, shift_amount);
val effective_addr = add(add(shifted_a, val_b), val_imm);
return effective_addr;
}
/*
compute_execute_result compute_execute(val op_z_or_d, val op_s, val imm,
bool sel_z_or_d, bool sel_s, bool sel_imm,
val shift_amount, bool use_agen,
val alu_op, val condition) {
val alu_input_b = or(val_b, val_imm);
val alu_result = alu_execute(alu_op, op_z_or_d, alu_input_b);
bool cond_met = comparator(condition, op_z_or_d, alu_input_b);
val result = or(use_if(!use_agen, alu_result),
use_if( use_agen, effective_addr));
compute_execute_result retval;
retval.result = result;
retval.cond_met = cond_met;
return retval;
}
*/