diff --git a/benchmarks/source/histogram_simple_test/README.md b/benchmarks/source/histogram_simple_test/README.md index 4599737f..ee177101 100644 --- a/benchmarks/source/histogram_simple_test/README.md +++ b/benchmarks/source/histogram_simple_test/README.md @@ -1 +1,3 @@ `run.m` fails with unrecognised command, as it seems stuck on the superH branch, even though typing the same commands by hand in sunflower works (where it picks up the riscv branch commands) + +(See issue #131). diff --git a/sim/Makefile b/sim/Makefile index 16a7cc57..81aff2f3 100755 --- a/sim/Makefile +++ b/sim/Makefile @@ -91,6 +91,7 @@ OBJS =\ sf-hitachi-sh.o\ sf-riscv.o\ taint.o\ + uncertain-histogram.o\ # decode-ti-msp430.o\ # dev430x1xx.o\ # machine-ti-msp430.o\ @@ -162,7 +163,7 @@ decode-riscv.h: latencies-riscv.h Makefile # Either of the lex-* would suffice for generating the LaTeX / help command array. # TODO Changed to riscv for now. This should be properly implemented as a union of lex-*, considering which -# parts of riscv/superh(/...) are duplicates +# parts of riscv/superh(/...) are duplicates. See issue #127. help.h: lex-hitachi-sh.c Makefile ./mkhelp $(GAWK) > help.h diff --git a/sim/config.h b/sim/config.h index 79233586..4244ea87 100755 --- a/sim/config.h +++ b/sim/config.h @@ -57,5 +57,7 @@ #define SF_BPTS 1 #define SF_TRAJECTORIES 1 #define SF_TAINTANALYSIS 1 +#define SF_UNCERTAIN_UPE 1 +#define SF_UNCERTAIN_HISTOGRAM 1 #define SF_NUMA 1 #define SF_EMBEDDED 0 diff --git a/sim/decode-hitachi-sh.h b/sim/decode-hitachi-sh.h index dbdbf366..fbd3af64 100644 --- a/sim/decode-hitachi-sh.h +++ b/sim/decode-hitachi-sh.h @@ -1,4 +1,4 @@ -/* This is dependent on latencies-hitachi-sh.h */ +/* DO NOTE EDIT! This file is auto-generated from latencies-hitachi-sh.h */ enum { SUPERH_OP_ADD, diff --git a/sim/decode-riscv.h b/sim/decode-riscv.h index 45e212e4..dbe4d181 100644 --- a/sim/decode-riscv.h +++ b/sim/decode-riscv.h @@ -1,4 +1,4 @@ -/* This is dependent on latencies-riscv.h */ +/* DO NOTE EDIT! This file is auto-generated from latencies-riscv.h. */ enum { RISCV_OP_LUI, diff --git a/sim/inst_uncertain.c b/sim/inst_uncertain.c index e94575a3..b729286b 100644 --- a/sim/inst_uncertain.c +++ b/sim/inst_uncertain.c @@ -1,859 +1,1034 @@ -#include "inst_uncertain.h" -#include "sf.h" +/* + Copyright (c) 2018-2019, Harry Sarson (author) + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include #include #include -#include #include -#include +#include "sf.h" -#define PRINT_DIGITS 5 -#define PRINT_JUST_REGISTERS 1 +enum +{ + PRINT_DIGITS = 5, + PRINT_JUST_REGISTERS = 1, + + /* + * unicode symbols may require 4 bytes + */ + PRINT_DIGIT_BUFFER_SIZE = (PRINT_DIGITS * 4 + 1), +}; -// unicode symbols may require 4 bytes -#define PRINT_DIGIT_BUFFER_SIZE (PRINT_DIGITS * 4 + 1) +#define EPSILON (1e-5f) -#define EPSILON (1e-5f) -static size_t covariances_in_mem (size_t memory_size) { - return (memory_size - 1) * memory_size / 2; + +static size_t +covariances_in_mem (size_t memory_size) +{ + return (memory_size - 1) * memory_size / 2; } -static size_t covariances_in_reg_mem (size_t register_size, size_t memory_size) { - return register_size * memory_size; + +static size_t +covariances_in_reg_mem (size_t register_size, size_t memory_size) +{ + return register_size * memory_size; } -// Access to uncertain registers -static int get_offset_reg_reg(int row, int col) +/* + * Access to uncertain registers + */ + + + +static int +get_offset_reg_reg(int row, int col) { - assert(row >= 0); - assert(col >= 1); - assert(row < col); - assert(col < UNCERTAIN_REGISTER_SIZE); - assert(row < UNCERTAIN_REGISTER_SIZE - 1); - return (col - 1 + row * (2 * UNCERTAIN_REGISTER_SIZE - 3 - row) / 2); + assert(row >= 0); + assert(col >= 1); + assert(row < col); + assert(col < kUncertainRegisterSize); + assert(row < kUncertainRegisterSize - 1); + + return (col - 1 + row * (2 * kUncertainRegisterSize - 3 - row) / 2); } -static int get_offset_reg_mem(int memory_size, int row, int col) +static int +get_offset_reg_mem(int memory_size, int row, int col) { - assert(row >= 0); - assert(col >= 0); - assert(col < memory_size); - assert(row < UNCERTAIN_REGISTER_SIZE); - return row *memory_size + col; + assert(row >= 0); + assert(col >= 0); + assert(col < memory_size); + assert(row < kUncertainRegisterSize); + + return row *memory_size + col; } -static float get_uncertain_variance_reg(UncertainState *state, int i) +static float +get_uncertain_variance_reg(UncertainState *state, int i) { - assert(i >= 0); - assert(i < UNCERTAIN_REGISTER_SIZE); - return state->registers.variances[i]; + assert(i >= 0); + assert(i < kUncertainRegisterSize); + + return state->registers.variances[i]; } -static void set_uncertain_variance_reg(UncertainState *state, int i, float value) +static void +set_uncertain_variance_reg(UncertainState *state, int i, float value) { - assert(i >= 0); - assert(i < UNCERTAIN_REGISTER_SIZE); - if (value < 0 && value > -EPSILON) { - value = 0; - } - assert(value >= 0 || isnan(value)); - state->registers.variances[i] = value; + assert(i >= 0); + assert(i < kUncertainRegisterSize); + + if (value < 0 && value > -EPSILON) + { + value = 0; + } + assert(value >= 0 || isnan(value)); + state->registers.variances[i] = value; } -static float get_uncertain_covariance_reg_reg(UncertainState *state, int row, int col) +static float +get_uncertain_covariance_reg_reg(UncertainState *state, int row, int col) { - int offset = get_offset_reg_reg(row, col); - return state->registers.covariances_reg_reg[offset]; + int offset = get_offset_reg_reg(row, col); + return state->registers.covariances_reg_reg[offset]; } -static void set_uncertain_covariance_reg_reg(UncertainState *state, int row, int col, float value) +static void +set_uncertain_covariance_reg_reg(UncertainState *state, int row, int col, float value) { - int offset = get_offset_reg_reg(row, col); - state->registers.covariances_reg_reg[offset] = value; + int offset = get_offset_reg_reg(row, col); + state->registers.covariances_reg_reg[offset] = value; } -static float get_uncertain_covariance_reg_mem(UncertainState *state, int row, int col) +static float +get_uncertain_covariance_reg_mem(UncertainState *state, int row, int col) { - int offset = get_offset_reg_mem(state->memory_size, row, col); - return state->registers.covariances_reg_mem[offset]; + int offset = get_offset_reg_mem(state->memory_size, row, col); + return state->registers.covariances_reg_mem[offset]; } -static void set_uncertain_covariance_reg_mem(UncertainState *state, int row, int col, float value) +static void +set_uncertain_covariance_reg_mem(UncertainState *state, int row, int col, float value) { - int offset = get_offset_reg_mem(state->memory_size, row, col); - state->registers.covariances_reg_mem[offset] = value; + int offset = get_offset_reg_mem(state->memory_size, row, col); + state->registers.covariances_reg_mem[offset] = value; } -// Access to uncertain memory -static int get_offset_mem_mem(int row, int col) + +/* + * Access to uncertain memory + */ + + + +static int +get_offset_mem_mem(int row, int col) { - assert(row >= 0); - assert(col >= 1); - assert(row < col); + assert(row >= 0); + assert(col >= 1); + assert(row < col); - return (col - 1) * col / 2 + row; + return (col - 1) * col / 2 + row; } -static float get_uncertain_variance_mem(UncertainState *state, int i) +static float +get_uncertain_variance_mem(UncertainState *state, int i) { - assert(i >= 0); - assert(i < state->memory_size); - return state->memory.variances[i]; + assert(i >= 0); + assert(i < state->memory_size); + + return state->memory.variances[i]; } -static void set_uncertain_variance_mem(UncertainState *state, int i, float value) +static void +set_uncertain_variance_mem(UncertainState *state, int i, float value) { - assert(i >= 0); - assert(i < state->memory_size); - if (value < 0 && value > -EPSILON) { - value = 0; - } - assert(value >= 0 || isnan(value)); - state->memory.variances[i] = value; + assert(i >= 0); + assert(i < state->memory_size); + + if (value < 0 && value > -EPSILON) + { + value = 0; + } + + assert(value >= 0 || isnan(value)); + state->memory.variances[i] = value; } -static float get_uncertain_covariance_mem_mem(UncertainState *state, int row, int col) +static float +get_uncertain_covariance_mem_mem(UncertainState *state, int row, int col) { - assert(row < state->memory_size - 1); - assert(col < state->memory_size); - int offset = get_offset_mem_mem(row, col); - return state->memory.covariances[offset]; + assert(row < state->memory_size - 1); + assert(col < state->memory_size); + int offset = get_offset_mem_mem(row, col); + + return state->memory.covariances[offset]; } -static void set_uncertain_covariance_mem_mem(UncertainState *state, int row, int col, float value) +static void +set_uncertain_covariance_mem_mem(UncertainState *state, int row, int col, float value) { - assert(row < state->memory_size - 1); - assert(col < state->memory_size); - int offset = get_offset_mem_mem(row, col); - state->memory.covariances[offset] = value; + assert(row < state->memory_size - 1); + assert(col < state->memory_size); + int offset = get_offset_mem_mem(row, col); + state->memory.covariances[offset] = value; } -// Uncertain operations -void uncertain_inst_lr(UncertainState *uncertain_state, int ud, int location) + +/* + * Uncertain operations + */ + + + +void +uncertain_inst_lr(UncertainState *uncertain_state, int ud, int location) { - int i; - float to_set; - assert(ud < UNCERTAIN_REGISTER_SIZE); - assert(location < uncertain_state->memory_size); - - // Load variance from memory and store in registers - to_set = get_uncertain_variance_mem(uncertain_state, location); - set_uncertain_variance_reg(uncertain_state, ud, to_set); - set_uncertain_covariance_reg_mem(uncertain_state, ud, location, to_set); - - // Load covariances from registers and store in registers - for (i = 0; i < ud; ++i) - { - to_set = get_uncertain_covariance_reg_mem(uncertain_state, i, location); - set_uncertain_covariance_reg_reg(uncertain_state, i, ud, to_set); - } - for (i = ud + 1; i < UNCERTAIN_REGISTER_SIZE; ++i) - { - to_set = get_uncertain_covariance_reg_mem(uncertain_state, i, location); - set_uncertain_covariance_reg_reg(uncertain_state, ud, i, to_set); - } - - // Load covariances from memory and store in registers - for (i = 0; i < location; ++i) - { - to_set = get_uncertain_covariance_mem_mem(uncertain_state, i, location); - set_uncertain_covariance_reg_mem(uncertain_state, ud, i, to_set); - } - for (i = location + 1; i < uncertain_state->memory_size; ++i) - { - to_set = get_uncertain_covariance_mem_mem(uncertain_state, location, i); - set_uncertain_covariance_reg_mem(uncertain_state, ud, i, to_set); - } + int i; + float to_set; + + assert(ud < kUncertainRegisterSize); + assert(location < uncertain_state->memory_size); + + /* + * Load variance from memory and store in registers + */ + to_set = get_uncertain_variance_mem(uncertain_state, location); + set_uncertain_variance_reg(uncertain_state, ud, to_set); + set_uncertain_covariance_reg_mem(uncertain_state, ud, location, to_set); + + /* + * Load covariances from registers and store in registers + */ + for (i = 0; i < ud; ++i) + { + to_set = get_uncertain_covariance_reg_mem(uncertain_state, i, location); + set_uncertain_covariance_reg_reg(uncertain_state, i, ud, to_set); + } + for (i = ud + 1; i < kUncertainRegisterSize; ++i) + { + to_set = get_uncertain_covariance_reg_mem(uncertain_state, i, location); + set_uncertain_covariance_reg_reg(uncertain_state, ud, i, to_set); + } + + /* + * Load covariances from memory and store in registers + */ + for (i = 0; i < location; ++i) + { + to_set = get_uncertain_covariance_mem_mem(uncertain_state, i, location); + set_uncertain_covariance_reg_mem(uncertain_state, ud, i, to_set); + } + for (i = location + 1; i < uncertain_state->memory_size; ++i) + { + to_set = get_uncertain_covariance_mem_mem(uncertain_state, location, i); + set_uncertain_covariance_reg_mem(uncertain_state, ud, i, to_set); + } } -void uncertain_inst_sr(UncertainState *uncertain_state, int us1, int location) +void +uncertain_inst_sr(UncertainState *uncertain_state, int us1, int location) { - int i; - float to_set; - assert(us1 >= 0); - assert(location >= 0); - assert(us1 < UNCERTAIN_REGISTER_SIZE); - assert(location < uncertain_state->memory_size); - - // Store variance - to_set = get_uncertain_variance_reg(uncertain_state, us1); - set_uncertain_variance_mem(uncertain_state, location, to_set); - set_uncertain_covariance_reg_mem(uncertain_state, us1, location, to_set); - - // Store covariances in registers - for (i = 0; i < us1; ++i) - { - to_set = get_uncertain_covariance_reg_reg(uncertain_state, i, us1); - set_uncertain_covariance_reg_mem(uncertain_state, i, location, to_set); - } - for (i = us1 + 1; i < UNCERTAIN_REGISTER_SIZE; ++i) - { - to_set = get_uncertain_covariance_reg_reg(uncertain_state, us1, i); - set_uncertain_covariance_reg_mem(uncertain_state, i, location, to_set); - } - - // Store covariances in memory - for (i = 0; i < location; ++i) - { - to_set = get_uncertain_covariance_reg_mem(uncertain_state, us1, i); - set_uncertain_covariance_mem_mem(uncertain_state, i, location, to_set); - } - for (i = location + 1; i < uncertain_state->memory_size; ++i) - { - to_set = get_uncertain_covariance_reg_mem(uncertain_state, us1, i); - set_uncertain_covariance_mem_mem(uncertain_state, location, i, to_set); - } + int i; + float to_set; + + assert(us1 >= 0); + assert(location >= 0); + assert(us1 < kUncertainRegisterSize); + assert(location < uncertain_state->memory_size); + + /* + * Store variance + */ + to_set = get_uncertain_variance_reg(uncertain_state, us1); + set_uncertain_variance_mem(uncertain_state, location, to_set); + set_uncertain_covariance_reg_mem(uncertain_state, us1, location, to_set); + + /* + * Store covariances in registers + */ + for (i = 0; i < us1; ++i) + { + to_set = get_uncertain_covariance_reg_reg(uncertain_state, i, us1); + set_uncertain_covariance_reg_mem(uncertain_state, i, location, to_set); + } + for (i = us1 + 1; i < kUncertainRegisterSize; ++i) + { + to_set = get_uncertain_covariance_reg_reg(uncertain_state, us1, i); + set_uncertain_covariance_reg_mem(uncertain_state, i, location, to_set); + } + + /* + * Store covariances in memory + */ + for (i = 0; i < location; ++i) + { + to_set = get_uncertain_covariance_reg_mem(uncertain_state, us1, i); + set_uncertain_covariance_mem_mem(uncertain_state, i, location, to_set); + } + for (i = location + 1; i < uncertain_state->memory_size; ++i) + { + to_set = get_uncertain_covariance_reg_mem(uncertain_state, us1, i); + set_uncertain_covariance_mem_mem(uncertain_state, location, i, to_set); + } } -void uncertain_inst_mv(UncertainState *uncertain_state, int ud, int us1) +void +uncertain_inst_mv(UncertainState *uncertain_state, int ud, int us1) { - uncertain_inst_up1(uncertain_state, ud, us1, 1.0f); + uncertain_inst_up1(uncertain_state, ud, us1, 1.0f); } -void uncertain_inst_up1(UncertainState *uncertain_state, int ud, int us1, float g1) +void +uncertain_inst_up1(UncertainState *uncertain_state, int ud, int us1, float g1) { - int i; - assert(ud < UNCERTAIN_REGISTER_SIZE); - assert(us1 < UNCERTAIN_REGISTER_SIZE); - - { - float new_var = - g1 * g1 * get_uncertain_variance_reg(uncertain_state, us1); - set_uncertain_variance_reg(uncertain_state, ud, new_var); - } - - for (i = 0; i < UNCERTAIN_REGISTER_SIZE; ++i) - { - if (i != ud) - { - float sigma; - if (i < us1) - { - sigma = get_uncertain_covariance_reg_reg(uncertain_state, i, us1); - } - else if (i == us1) - { - sigma = get_uncertain_variance_reg(uncertain_state, us1); - } - else - { - sigma = get_uncertain_covariance_reg_reg(uncertain_state, us1, i); - } - - float new_covar = g1 * sigma; - - if (i < ud) - { - set_uncertain_covariance_reg_reg(uncertain_state, i, ud, new_covar); - } - else - { - set_uncertain_covariance_reg_reg(uncertain_state, ud, i, new_covar); - } - } - } - for (i = 0; i < uncertain_state->memory_size; ++i) - { - float new_covar = - g1 * get_uncertain_covariance_reg_mem(uncertain_state, us1, i); - set_uncertain_covariance_reg_mem(uncertain_state, ud, i, new_covar); - } + int i; + + assert(ud < kUncertainRegisterSize); + assert(us1 < kUncertainRegisterSize); + + { + float new_var = + g1 * g1 * get_uncertain_variance_reg(uncertain_state, us1); + set_uncertain_variance_reg(uncertain_state, ud, new_var); + } + + for (i = 0; i < kUncertainRegisterSize; ++i) + { + if (i != ud) + { + float sigma; + if (i < us1) + { + sigma = get_uncertain_covariance_reg_reg(uncertain_state, i, us1); + } + else if (i == us1) + { + sigma = get_uncertain_variance_reg(uncertain_state, us1); + } + else + { + sigma = get_uncertain_covariance_reg_reg(uncertain_state, us1, i); + } + + float new_covar = g1 * sigma; + + if (i < ud) + { + set_uncertain_covariance_reg_reg(uncertain_state, i, ud, new_covar); + } + else + { + set_uncertain_covariance_reg_reg(uncertain_state, ud, i, new_covar); + } + } + } + for (i = 0; i < uncertain_state->memory_size; ++i) + { + float new_covar = + g1 * get_uncertain_covariance_reg_mem(uncertain_state, us1, i); + set_uncertain_covariance_reg_mem(uncertain_state, ud, i, new_covar); + } } -void uncertain_inst_up2(UncertainState *uncertain_state, int ud, int us1, int us2, float g1, float g2) +void +uncertain_inst_up2(UncertainState *uncertain_state, int ud, int us1, int us2, float g1, float g2) { - int i; - assert(ud < UNCERTAIN_REGISTER_SIZE); - assert(us1 < UNCERTAIN_REGISTER_SIZE); - assert(us2 < UNCERTAIN_REGISTER_SIZE); - - { - float new_var; - if (us1 < us2) - { - new_var = - g1 * g1 * get_uncertain_variance_reg(uncertain_state, us1) + - 2 * g1 * g2 * get_uncertain_covariance_reg_reg(uncertain_state, us1, us2) + - g2 * g2 * get_uncertain_variance_reg(uncertain_state, us2); - } - else if (us1 > us2) - { - new_var = - g1 * g1 * get_uncertain_variance_reg(uncertain_state, us1) + - 2 * g1 * g2 * get_uncertain_covariance_reg_reg(uncertain_state, us2, us1) + - g2 * g2 * get_uncertain_variance_reg(uncertain_state, us2); - } - else - { - new_var = - (g1 + g2) * (g1 + g2) * get_uncertain_variance_reg(uncertain_state, us1); - } - set_uncertain_variance_reg(uncertain_state, ud, new_var); - } - - for (i = 0; i < UNCERTAIN_REGISTER_SIZE; ++i) - { - if (i != ud) - { - float sigma1 = nanf(""); - if (i < us1) - { - sigma1 = get_uncertain_covariance_reg_reg(uncertain_state, i, us1); - } - else if (i == us1) - { - sigma1 = get_uncertain_variance_reg(uncertain_state, i); - } - else - { - sigma1 = get_uncertain_covariance_reg_reg(uncertain_state, us1, i); - } - - float sigma2 = nanf(""); - if (i < us2) - { - sigma2 = get_uncertain_covariance_reg_reg(uncertain_state, i, us2); - } - else if (i == us2) - { - sigma2 = get_uncertain_variance_reg(uncertain_state, i); - } - else - { - sigma2 = get_uncertain_covariance_reg_reg(uncertain_state, us2, i); - } - - float new_covar = g1 * sigma1 + g2 * sigma2; - - if (i < ud) - { - set_uncertain_covariance_reg_reg(uncertain_state, i, ud, new_covar); - } - else - { - set_uncertain_covariance_reg_reg(uncertain_state, ud, i, new_covar); - } - } - } - for (i = 0; i < uncertain_state->memory_size; ++i) - { - float new_covar = - g1 * get_uncertain_covariance_reg_mem(uncertain_state, us1, i) + - g2 * get_uncertain_covariance_reg_mem(uncertain_state, us2, i); - set_uncertain_covariance_reg_mem(uncertain_state, ud, i, new_covar); - } + int i; + + assert(ud < kUncertainRegisterSize); + assert(us1 < kUncertainRegisterSize); + assert(us2 < kUncertainRegisterSize); + + { + float new_var; + if (us1 < us2) + { + new_var = + g1 * g1 * get_uncertain_variance_reg(uncertain_state, us1) + + 2 * g1 * g2 * get_uncertain_covariance_reg_reg(uncertain_state, us1, us2) + + g2 * g2 * get_uncertain_variance_reg(uncertain_state, us2); + } + else if (us1 > us2) + { + new_var = + g1 * g1 * get_uncertain_variance_reg(uncertain_state, us1) + + 2 * g1 * g2 * get_uncertain_covariance_reg_reg(uncertain_state, us2, us1) + + g2 * g2 * get_uncertain_variance_reg(uncertain_state, us2); + } + else + { + new_var = + (g1 + g2) * (g1 + g2) * get_uncertain_variance_reg(uncertain_state, us1); + } + set_uncertain_variance_reg(uncertain_state, ud, new_var); + } + + for (i = 0; i < kUncertainRegisterSize; ++i) + { + if (i != ud) + { + float sigma1 = nanf(""); + if (i < us1) + { + sigma1 = get_uncertain_covariance_reg_reg(uncertain_state, i, us1); + } + else if (i == us1) + { + sigma1 = get_uncertain_variance_reg(uncertain_state, i); + } + else + { + sigma1 = get_uncertain_covariance_reg_reg(uncertain_state, us1, i); + } + + float sigma2 = nanf(""); + if (i < us2) + { + sigma2 = get_uncertain_covariance_reg_reg(uncertain_state, i, us2); + } + else if (i == us2) + { + sigma2 = get_uncertain_variance_reg(uncertain_state, i); + } + else + { + sigma2 = get_uncertain_covariance_reg_reg(uncertain_state, us2, i); + } + + float new_covar = g1 * sigma1 + g2 * sigma2; + + if (i < ud) + { + set_uncertain_covariance_reg_reg(uncertain_state, i, ud, new_covar); + } + else + { + set_uncertain_covariance_reg_reg(uncertain_state, ud, i, new_covar); + } + } + } + for (i = 0; i < uncertain_state->memory_size; ++i) + { + float new_covar = + g1 * get_uncertain_covariance_reg_mem(uncertain_state, us1, i) + + g2 * get_uncertain_covariance_reg_mem(uncertain_state, us2, i); + set_uncertain_covariance_reg_mem(uncertain_state, ud, i, new_covar); + } } -void uncertain_inst_sv(UncertainState *uncertain_state, int ud, float variance) +void +uncertain_inst_sv(UncertainState *uncertain_state, int ud, float variance) { - int i; - assert(ud < UNCERTAIN_REGISTER_SIZE); - assert(variance >= 0 || isnan(variance)); - - set_uncertain_variance_reg(uncertain_state, ud, variance); - - for (i = 0; i < ud; ++i) - { - set_uncertain_covariance_reg_reg(uncertain_state, i, ud, 0); - } - - for (i = ud + 1; i < UNCERTAIN_REGISTER_SIZE; ++i) - { - set_uncertain_covariance_reg_reg(uncertain_state, ud, i, 0); - } - - for (i = 0; i < uncertain_state->memory_size; ++i) - { - set_uncertain_covariance_reg_mem(uncertain_state, ud, i, 0); - } + int i; + + assert(ud < kUncertainRegisterSize); + assert(variance >= 0 || isnan(variance)); + + set_uncertain_variance_reg(uncertain_state, ud, variance); + + for (i = 0; i < ud; ++i) + { + set_uncertain_covariance_reg_reg(uncertain_state, i, ud, 0); + } + + for (i = ud + 1; i < kUncertainRegisterSize; ++i) + { + set_uncertain_covariance_reg_reg(uncertain_state, ud, i, 0); + } + + for (i = 0; i < uncertain_state->memory_size; ++i) + { + set_uncertain_covariance_reg_mem(uncertain_state, ud, i, 0); + } } -float uncertain_inst_gv(UncertainState *uncertain_state, int us1) +float +uncertain_inst_gv(UncertainState *uncertain_state, int us1) { - assert(us1 < UNCERTAIN_REGISTER_SIZE); - return get_uncertain_variance_reg(uncertain_state, us1); + assert(us1 < kUncertainRegisterSize); + return get_uncertain_variance_reg(uncertain_state, us1); } -float uncertain_inst_gcov(UncertainState *uncertain_state, int us1, int us2) +float +uncertain_inst_gcov(UncertainState *uncertain_state, int us1, int us2) { - assert(us1 < UNCERTAIN_REGISTER_SIZE); - assert(us2 < UNCERTAIN_REGISTER_SIZE); - if (us1 == us2) - return get_uncertain_variance_reg(uncertain_state, us1); - else - return get_uncertain_covariance_reg_reg(uncertain_state, us1, us2); + assert(us1 < kUncertainRegisterSize); + assert(us2 < kUncertainRegisterSize); + if (us1 == us2) + { + return get_uncertain_variance_reg(uncertain_state, us1); + } + else + { + return get_uncertain_covariance_reg_reg(uncertain_state, us1, us2); + } } -void uncertain_sizemen(Engine *E, State *S, int size) +void +uncertain_sizemen(Engine *E, State *S, int size) { - size = (size - 0x4000) / 4; - void *tmp; + void * tmp; + + + if (!SF_UNCERTAIN_UPE) + { + return; + } - if (size > (1<< 16)) { - mexit(E, "Cannot compute required number of covariances without overflow\n", 1); - } + /* + * This used to be + * + * size = (size - 0x4000) / 4 + * + * That is no longer correct as the S->MEMBASE is now adaptible + * and memory also no longer always starts at offset 0x4000 from + * MEMBASE. In any case, + */ + size /= 4; + + if (size > (1<< 16)) + { + mexit(E, "Cannot compute required number of covariances without overflow\n", 1); + } - size_t variance_bytes = size * sizeof(float); - size_t covariance_bytes = covariances_in_mem(size) * sizeof(float); - size_t register_bytes = covariances_in_reg_mem(UNCERTAIN_REGISTER_SIZE, size) * sizeof(float); - size_t required_bytes = variance_bytes + covariance_bytes + register_bytes; + size_t variance_bytes = size * sizeof(float); + size_t covariance_bytes = covariances_in_mem(size) * sizeof(float); + size_t register_bytes = covariances_in_reg_mem(kUncertainRegisterSize, size) * sizeof(float); + size_t required_bytes = variance_bytes + covariance_bytes + register_bytes; if (S->riscv->uncertain->memory_size == 0) { - assert(S->riscv->uncertain->memory.variances == NULL); - assert(S->riscv->uncertain->memory.covariances == NULL); - assert(S->riscv->uncertain->registers.covariances_reg_mem == NULL); + assert(S->riscv->uncertain->memory.variances == NULL); + assert(S->riscv->uncertain->memory.covariances == NULL); + assert(S->riscv->uncertain->registers.covariances_reg_mem == NULL); tmp = mcalloc(E, 1, required_bytes, "S->riscv->uncertain_memory"); if (tmp == NULL) { mexit(E, "Could not allocate mem for uncertain memory\n", -1); } - S->riscv->uncertain->memory.variances = tmp; - S->riscv->uncertain->memory.covariances = tmp + variance_bytes; - S->riscv->uncertain->registers.covariances_reg_mem = tmp + variance_bytes + covariance_bytes; - S->riscv->uncertain->memory_size = size; + S->riscv->uncertain->memory.variances = tmp; + S->riscv->uncertain->memory.covariances = tmp + variance_bytes; + S->riscv->uncertain->registers.covariances_reg_mem = tmp + variance_bytes + covariance_bytes; + S->riscv->uncertain->memory_size = size; return; } - assert(S->riscv->uncertain->memory.variances != NULL); - assert(S->riscv->uncertain->memory.covariances != NULL); - assert(S->riscv->uncertain->registers.covariances_reg_mem != NULL); + assert(S->riscv->uncertain->memory.variances != NULL); + assert(S->riscv->uncertain->memory.covariances != NULL); + assert(S->riscv->uncertain->registers.covariances_reg_mem != NULL); tmp = mrealloc(E, S->riscv->uncertain->memory.variances, required_bytes, "S->riscv->uncertain_memory"); if (tmp == NULL) { - mexit(E, - "SIZEMEM failed: could not allocate uncertain memory\n", -1); + mexit(E, "SIZEMEM failed: could not allocate uncertain memory\n", -1); } else { - S->riscv->uncertain->memory.variances = tmp; - S->riscv->uncertain->memory.covariances = tmp + variance_bytes; - S->riscv->uncertain->registers.covariances_reg_mem = tmp + variance_bytes + covariance_bytes; - S->riscv->uncertain->memory_size = size; - mprint(E, S, nodeinfo, - "Set uncertain memory size to %d values\n", size); + S->riscv->uncertain->memory.variances = tmp; + S->riscv->uncertain->memory.covariances = tmp + variance_bytes; + S->riscv->uncertain->registers.covariances_reg_mem = tmp + variance_bytes + covariance_bytes; + S->riscv->uncertain->memory_size = size; + mprint(E, S, nodeinfo, "Set uncertain memory size to %d values\n", size); } return; } - -static int print_register_row(UncertainState *uncertain_state, FILE *stream, int row) +static int +print_register_row(UncertainState *uncertain_state, FILE *stream, int row) { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-truncation" - int i, result; - int characters_written = 0; - char buffer[PRINT_DIGIT_BUFFER_SIZE] = {'\0'}; - - result = snprintf(buffer, PRINT_DIGITS + 1, " u%-*d", - PRINT_DIGITS, row); - - if (result < 0) - { - return result; - } - result = fprintf(stream, "%s│", buffer); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - - for (i = 0; i < UNCERTAIN_REGISTER_SIZE; ++i) - { - if (i < row) - { - memset(buffer, ' ', PRINT_DIGITS); - } - else if (i == row) - { - float var = get_uncertain_variance_reg(uncertain_state, row); - result = snprintf(buffer, PRINT_DIGITS + 1, "%#-*.*f", - PRINT_DIGITS, PRINT_DIGITS, var); - if (result < 0) - { - return result; - } - } - else - { - float covar = get_uncertain_covariance_reg_reg(uncertain_state, row, i); - if (covar == 0) { - result = snprintf(buffer, PRINT_DIGITS + 1, "%-*d", PRINT_DIGITS, 0); - } else { - result = snprintf(buffer, PRINT_DIGITS + 1, "%#-*.*f", - PRINT_DIGITS, PRINT_DIGITS, covar); - } - if (result < 0) - { - return result; - } - } - const char *padding; - if (i == 0) - padding = ""; - else - padding = " "; - result = fprintf(stream, "%s%s", padding, buffer); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - } - - if (!PRINT_JUST_REGISTERS) - { - for (i = 0; i < uncertain_state->memory_size; ++i) - { - float covar = get_uncertain_covariance_reg_mem(uncertain_state, row, i); - result = snprintf(buffer, PRINT_DIGITS + 1, "%-*.*g", - PRINT_DIGITS, PRINT_DIGITS - 2 - (int)ceil(fabs(log10(covar))), covar); - if (result < 0) - { - return result; - } - const char *padding; - if (i == 0) - padding = "│"; - else - padding = " "; - result = fprintf(stream, "%s%s", padding, buffer); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - } - } - - result = fprintf(stream, "│\n"); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - - return characters_written; -#pragma GCC diagnostic pop + int i, result; + int characters_written = 0; + char buffer[PRINT_DIGIT_BUFFER_SIZE] = {'\0'}; + + result = snprintf(buffer, PRINT_DIGITS + 1, " u%-*d", PRINT_DIGITS, row); + + if (result < 0) + { + return result; + } + result = fprintf(stream, "%s│", buffer); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + + for (i = 0; i < kUncertainRegisterSize; ++i) + { + if (i < row) + { + memset(buffer, ' ', PRINT_DIGITS); + } + else if (i == row) + { + float var = get_uncertain_variance_reg(uncertain_state, row); + result = snprintf(buffer, PRINT_DIGITS + 1, "%#-*.*f", + PRINT_DIGITS, PRINT_DIGITS, var); + if (result < 0) + { + return result; + } + } + else + { + float covar = get_uncertain_covariance_reg_reg(uncertain_state, row, i); + if (covar == 0) + { + result = snprintf(buffer, PRINT_DIGITS + 1, "%-*d", PRINT_DIGITS, 0); + } + else + { + result = snprintf(buffer, PRINT_DIGITS + 1, "%#-*.*f", + PRINT_DIGITS, PRINT_DIGITS, covar); + } + + if (result < 0) + { + return result; + } + } + const char *padding; + if (i == 0) + { + padding = ""; + } + else + { + padding = " "; + } + + result = fprintf(stream, "%s%s", padding, buffer); + + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + } + + if (!PRINT_JUST_REGISTERS) + { + for (i = 0; i < uncertain_state->memory_size; ++i) + { + float covar = get_uncertain_covariance_reg_mem(uncertain_state, row, i); + result = snprintf(buffer, PRINT_DIGITS + 1, "%-*.*g", + PRINT_DIGITS, PRINT_DIGITS - 2 - (int)ceil(fabs(log10(covar))), covar); + if (result < 0) + { + return result; + } + const char *padding; + if (i == 0) + { + padding = "│"; + } + else + { + padding = " "; + } + + result = fprintf(stream, "%s%s", padding, buffer); + + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + } + } + + result = fprintf(stream, "│\n"); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + + return characters_written; } -static int print_memory_row(UncertainState *uncertain_state, FILE *stream, int row, const char *stack_indicator) +static int +print_memory_row(UncertainState *uncertain_state, FILE *stream, int row, const char *stack_indicator) { - int i, result; - int characters_written = 0; - char buffer[PRINT_DIGIT_BUFFER_SIZE] = {'\0'}; - - result = fprintf(stream, " %-*.*s│", - PRINT_DIGITS - 1, PRINT_DIGITS - 1, stack_indicator); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - - for (i = 0; i < UNCERTAIN_REGISTER_SIZE; ++i) - { - memset(buffer, ' ', PRINT_DIGITS); - const char *padding; - if (i == 0) - padding = ""; - else - padding = " "; - result = fprintf(stream, "%s%s", padding, buffer); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - } - - result = fprintf(stream, "│"); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - - for (i = 0; i < uncertain_state->memory_size; ++i) - { - if (i < row) - { - memset(buffer, ' ', PRINT_DIGITS); - } - else if (i == row) - { - float var = get_uncertain_variance_mem(uncertain_state, row); - result = snprintf(buffer, PRINT_DIGITS + 1, "%-*.*g", - PRINT_DIGITS, PRINT_DIGITS - 2 - (int)ceil(fabs(log10(var))), var); - if (result < 0) - { - return result; - } - } - else - { - float covar = get_uncertain_covariance_mem_mem(uncertain_state, row, i); - result = snprintf(buffer, PRINT_DIGITS + 1, "%-*.*g", - PRINT_DIGITS, PRINT_DIGITS - 2 - (int)ceil(fabs(log10(covar))), covar); - if (result < 0) - { - return result; - } - } - const char *padding; - if (i == 0) - padding = ""; - else - padding = " "; - result = fprintf(stream, "%s%s", padding, buffer); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - } - - result = fprintf(stream, "│\n"); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - - return characters_written; + int i, result; + int characters_written = 0; + char buffer[PRINT_DIGIT_BUFFER_SIZE] = {'\0'}; + + result = fprintf(stream, " %-*.*s│", PRINT_DIGITS - 1, PRINT_DIGITS - 1, stack_indicator); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + + for (i = 0; i < kUncertainRegisterSize; ++i) + { + memset(buffer, ' ', PRINT_DIGITS); + const char *padding; + if (i == 0) + { + padding = ""; + } + else + { + padding = " "; + } + + result = fprintf(stream, "%s%s", padding, buffer); + + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + } + + result = fprintf(stream, "│"); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + + for (i = 0; i < uncertain_state->memory_size; ++i) + { + if (i < row) + { + memset(buffer, ' ', PRINT_DIGITS); + } + else if (i == row) + { + float var = get_uncertain_variance_mem(uncertain_state, row); + result = snprintf(buffer, PRINT_DIGITS + 1, "%-*.*g", + PRINT_DIGITS, PRINT_DIGITS - 2 - (int)ceil(fabs(log10(var))), var); + if (result < 0) + { + return result; + } + } + else + { + float covar = get_uncertain_covariance_mem_mem(uncertain_state, row, i); + result = snprintf(buffer, PRINT_DIGITS + 1, "%-*.*g", + PRINT_DIGITS, PRINT_DIGITS - 2 - (int)ceil(fabs(log10(covar))), covar); + if (result < 0) + { + return result; + } + } + const char *padding; + if (i == 0) + { + padding = ""; + } + else + { + padding = " "; + } + + result = fprintf(stream, "%s%s", padding, buffer); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + } + + result = fprintf(stream, "│\n"); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + + return characters_written; } -static int print_extreme_row(UncertainState *uncertain_state, FILE *stream, const char *label, const char *open, const char *close) +static int +print_extreme_row(UncertainState *uncertain_state, FILE *stream, const char *label, const char *open, const char *close) { - int i, len, result; - int characters_written = 0; - char buffer[PRINT_DIGIT_BUFFER_SIZE] = {'\0'}; - - result = snprintf(buffer, PRINT_DIGITS + 1, "%-*s", - PRINT_DIGITS, label); - if (result < 0) - { - return result; - } - result = fprintf(stream, "%s%s", buffer, open); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - - for (i = 0, len = PRINT_JUST_REGISTERS ? UNCERTAIN_REGISTER_SIZE : UNCERTAIN_REGISTER_SIZE + uncertain_state->memory_size; - i < len; - ++i) - { - memset(buffer, ' ', PRINT_DIGITS); - const char *padding; - if (i == 0) - padding = ""; - else - padding = " "; - result = fprintf(stream, "%s%s", padding, buffer); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - } - result = fprintf(stream, "%s\n", close); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - - return characters_written; + int i, len, result; + int characters_written = 0; + char buffer[PRINT_DIGIT_BUFFER_SIZE] = {'\0'}; + + result = snprintf(buffer, PRINT_DIGITS + 1, "%-*s", PRINT_DIGITS, label); + if (result < 0) + { + return result; + } + + result = fprintf(stream, "%s%s", buffer, open); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + + for ( i = 0, len = (PRINT_JUST_REGISTERS ? kUncertainRegisterSize : kUncertainRegisterSize + uncertain_state->memory_size); + i < len; + ++i) + { + const char * padding; + + memset(buffer, ' ', PRINT_DIGITS); + + if (i == 0) + { + padding = ""; + } + else + { + padding = " "; + } + + result = fprintf(stream, "%s%s", padding, buffer); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + } + + result = fprintf(stream, "%s\n", close); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + + return characters_written; } -static int print_middle_row(UncertainState *uncertain_state, FILE *stream) +static int +print_middle_row(UncertainState *uncertain_state, FILE *stream) { - int i, j, result; - int characters_written = 0; - char buffer[PRINT_DIGIT_BUFFER_SIZE] = {'\0'}; - - memset(buffer, ' ', PRINT_DIGITS); - result = fprintf(stream, "%s├", buffer); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - - for (i = 0; i < UNCERTAIN_REGISTER_SIZE + uncertain_state->memory_size; ++i) - { - const char *padding; - if (i == 0) - padding = ""; - else if (i == UNCERTAIN_REGISTER_SIZE) - padding = "┼"; // " └"; - else - padding = "─"; - - result = fprintf(stream, "%s", padding); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - for (j = 0; j < PRINT_DIGITS; ++j) - { - result = fprintf(stream, "─"); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - } - } - - result = fprintf(stream, "┤\n"); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - - return characters_written; + int i, j, result; + int characters_written = 0; + char buffer[PRINT_DIGIT_BUFFER_SIZE] = {'\0'}; + + memset(buffer, ' ', PRINT_DIGITS); + + result = fprintf(stream, "%s├", buffer); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + + for (i = 0; i < kUncertainRegisterSize + uncertain_state->memory_size; ++i) + { + const char *padding; + if (i == 0) + { + padding = ""; + } + else if (i == kUncertainRegisterSize) + { + padding = "┼"; // " └"; + } + else + { + padding = "─"; + } + + result = fprintf(stream, "%s", padding); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + for (j = 0; j < PRINT_DIGITS; ++j) + { + result = fprintf(stream, "─"); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + } + } + + result = fprintf(stream, "┤\n"); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + + return characters_written; } -int uncertain_print_system(UncertainState *uncertain_state, FILE *stream) +int +uncertain_print_system(UncertainState *uncertain_state, FILE *stream) { - int i, result; - int characters_written = 0; - - result = print_extreme_row(uncertain_state, stream, "REG", "┌", "┐"); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - - for (i = 0; i < UNCERTAIN_REGISTER_SIZE; ++i) - { - result = print_register_row(uncertain_state, stream, i); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - } - - if (PRINT_JUST_REGISTERS) - { - result = print_extreme_row(uncertain_state, stream, "", "└", "┘"); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - } - else - { - - - result = print_middle_row(uncertain_state, stream); - - // TODO: read stack_point from CSR - // int stack_pointer = uncertain_inst_addisp(0); - - for (i = 0; i < uncertain_state->memory_size; ++i) - { - const char *label = ""; - // if (i == stack_pointer) - // label = "^"; - // else if (i > stack_pointer) - // label = "|"; - - result = print_memory_row(uncertain_state, stream, i, label); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - } - - result = print_extreme_row(uncertain_state, stream, "stack", "└", "┘"); - if (result < 0) - { - return result; - } - else - { - characters_written += result; - } - } - - return characters_written; + int i, result; + int characters_written = 0; + + result = print_extreme_row(uncertain_state, stream, "REG", "┌", "┐"); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + + for (i = 0; i < kUncertainRegisterSize; ++i) + { + result = print_register_row(uncertain_state, stream, i); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + } + + if (PRINT_JUST_REGISTERS) + { + result = print_extreme_row(uncertain_state, stream, "", "└", "┘"); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + } + else + { + result = print_middle_row(uncertain_state, stream); + + /* + * TODO: read stack_point from CSR + */ + // int stack_pointer = uncertain_inst_addisp(0); + + for (i = 0; i < uncertain_state->memory_size; ++i) + { + const char *label = ""; + // if (i == stack_pointer) + // label = "^"; + // else if (i > stack_pointer) + // label = "|"; + + result = print_memory_row(uncertain_state, stream, i, label); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + } + + result = print_extreme_row(uncertain_state, stream, "stack", "└", "┘"); + if (result < 0) + { + return result; + } + else + { + characters_written += result; + } + } + + return characters_written; } diff --git a/sim/inst_uncertain.h b/sim/inst_uncertain.h index 5c2cbc36..632edc71 100644 --- a/sim/inst_uncertain.h +++ b/sim/inst_uncertain.h @@ -1,70 +1,81 @@ -#ifndef INSTR_UNCERTAIN_H -#define INSTR_UNCERTAIN_H - -#include -#include -#include - -#define UNCERTAIN_REGISTER_SIZE 32 - -#define COVARIANCES_REG_REG (((UNCERTAIN_REGISTER_SIZE - 1) * UNCERTAIN_REGISTER_SIZE) / 2) +/* + Copyright (c) 2018-2019, Harry Sarson (author) + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +enum +{ + kUncertainRegisterSize = 32, +}; -struct Engine; -typedef struct Engine Engine; -struct State; -typedef struct State State; +enum +{ + COVARIANCES_REG_REG = (((kUncertainRegisterSize - 1) * kUncertainRegisterSize) / 2) +}; typedef struct { - float *variances; - float *covariances; + float * variances; + float * covariances; } UncertainMemory; typedef struct { - float variances[UNCERTAIN_REGISTER_SIZE]; - float covariances_reg_reg[COVARIANCES_REG_REG]; - float *covariances_reg_mem; + float variances[kUncertainRegisterSize]; + float covariances_reg_reg[COVARIANCES_REG_REG]; + float * covariances_reg_mem; } UncertainRegisters; -typedef enum { - UncertainOperationNone, - UncertainOperationLoadStore, - UncertainOperationUpdate, +typedef enum +{ + UncertainOperationNone, + UncertainOperationLoadStore, + UncertainOperationUpdate, } UncertainOperationType; typedef struct { - uint32_t op_fp_pc; - uint32_t insn_part1; - int valid; + uint32_t op_fp_pc; + uint32_t insn_part1; + int valid; } UncertainUpdateInfo; -typedef struct { - UncertainUpdateInfo last_op; - UncertainMemory memory; - UncertainRegisters registers; - int memory_size; +typedef struct +{ + UncertainUpdateInfo last_op; + UncertainMemory memory; + UncertainRegisters registers; + int memory_size; } UncertainState; - -int uncertain_print_system(UncertainState * state, FILE *stream); -void uncertain_sizemen(Engine *E, State *S, int size); - -void uncertain_inst_lr(UncertainState * state, int ud, int location); -void uncertain_inst_sr(UncertainState * state, int us1, int location); - -void uncertain_inst_mv(UncertainState * state, int ud, int us1); - -void uncertain_inst_up1(UncertainState * state, - int ud, int us1, - float g1); - -void uncertain_inst_up2(UncertainState * state, - int ud, int us1, int us2, - float g1, float g2); - -float uncertain_inst_gv(UncertainState * state, int us1); -float uncertain_inst_gcov(UncertainState * state, int us1, int us2); -void uncertain_inst_sv(UncertainState * state, int ud, float variance); - -#endif diff --git a/sim/instr-riscv.h b/sim/instr-riscv.h index 269266da..569aa1ca 100644 --- a/sim/instr-riscv.h +++ b/sim/instr-riscv.h @@ -35,7 +35,9 @@ POSSIBILITY OF SUCH DAMAGE. */ -/*From Figure 2.3 in https://riscv.org/specifications/ v2.2 */ +/* + * From Figure 2.3 in https://riscv.org/specifications/ v2.2 + */ enum { diff --git a/sim/machine-hitachi-sh.h b/sim/machine-hitachi-sh.h index 17e0693b..9c271388 100755 --- a/sim/machine-hitachi-sh.h +++ b/sim/machine-hitachi-sh.h @@ -38,16 +38,16 @@ enum { /* Max num of chars in a deassembled instruction. */ - INSTRBUFSIZE = 128, + INSTRBUFSIZE = 128, SUPERH_MEMBASE = 0x08000000, SUPERH_FLASHBASE = 0x00000000, SUPERH_BYTES_PER_POINTER = 4, SUPERH_MEMADDRBITS = 32, - /* Max num of chars in an opcode name eg ADD = 3 */ - MAX_OPCHARS = 16, - DEFAULT_MISS_PENALTY = 100, + /* Max num of chars in an opcode name eg ADD = 3 */ + MAX_OPCHARS = 16, + DEFAULT_MISS_PENALTY = 100, }; /* */ @@ -103,7 +103,7 @@ struct SuperHState SuperHBuses *B; - /* Exception queue */ + /* Exception queue */ InterruptQ *excpQ; /* */ @@ -171,7 +171,7 @@ struct SuperHState int mem_access_type; - /* Exception and trap mmap regs */ + /* Exception and trap mmap regs */ ulong TRA; ulong EXPEVT; ulong INTEVT; diff --git a/sim/machine-riscv.c b/sim/machine-riscv.c index aad2aa01..e196d724 100644 --- a/sim/machine-riscv.c +++ b/sim/machine-riscv.c @@ -1,3 +1,39 @@ +/* + Copyright (c) 2017-2018, Zhengyang Gu (author) + 2018-2019, Harry Sarson (author) + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ #include #include #include "sf.h" @@ -6,7 +42,9 @@ static void print_integer_register_abi(Engine *E, State *S, ulong reg_index) { - // See https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#integer-register-convention- + /* + * See https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#integer-register-convention- + */ const char * special_names[] = { "zero", "ra", @@ -47,7 +85,9 @@ print_integer_register_abi(Engine *E, State *S, ulong reg_index) static void print_fp_register_abi(Engine *E, State *S, ulong reg_index) { - // See https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#floating-point-register-convention- + /* + * See https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#floating-point-register-convention- + */ if (reg_index < 8) { mprint(E, S, nodeinfo, "ft%-2u", reg_index); @@ -112,9 +152,9 @@ riscvstallaction(Engine *E, State *S, ulong addr, int type, int latency) void riscvdumpregs(Engine *E, State *S) { - int i; - char fp_value[128]; - char * f_width; + int i; + char fp_value[128]; + char * f_width; for (i = 0; i < 32; i++) { @@ -159,18 +199,20 @@ riscvdumpregs(Engine *E, State *S) mprint(E, S, nodeinfo, "%-23s (%s) [0x%016llx]\n", fp_value, f_width, S->riscv->fR[i]); } - // TODO: remove me! - // uncertain_print_system(S->riscv->uncertain, stdout); - return; } -void/* riscv does not have system registers */ -riscvdumpsysregs(){} + +void +riscvdumpsysregs() +{ + /* + * RISC-V does not have system registers + */ +} void riscvfatalaction(Engine *E, State *S) { - //superHdumptlb(E, S); Blindly copied over from superH version. mprint(E, S, nodeinfo, "FATAL (node %d): P.EX=[%s]\n",\ S->NODE_ID, riscv_opstrs[S->riscv->P.EX.op]); @@ -181,42 +223,56 @@ riscvfatalaction(Engine *E, State *S) /* - * Histograms + * Histograms + */ + +/* + * Print histogram */ -// Print histogram void -riscvdumphist(Engine *E, State *S, int histogram_id){ +riscvdumphist(Engine *E, State *S, int histogram_id) +{ mprint(E, S, nodeinfo, "Printing information for register %u\n", histogram_id); mprint(E, S, nodeinfo, "bin | val \n"); mprint(E, S, nodeinfo, "----+-----\n"); - for (int i = 0; i < kNBINS; i++){ + for (int i = 0; i < kUncertainAluHistogramBins; i++) + { mprint(E, S, nodeinfo, "%03u | %-3u\n", i, S->riscv->histograms[histogram_id].bins[i]); } return; } -// Print histogram with extra stats and ASCII graphics +/* + * Print histogram with extra stats and ASCII graphics + */ void -riscvdumphistpretty(Engine *E, State *S, int histogram_id){ +riscvdumphistpretty(Engine *E, State *S, int histogram_id) +{ mprint(E, S, nodeinfo, "Printing information for register %u\n", histogram_id); Histogram_PrettyPrint(E, S, &S->riscv->histograms[histogram_id]); - + return; } -// Load histogram with bin values randomly filled +/* + * Load histogram with bin values randomly filled + */ void -riscvldhistrandom(Engine *E, State *S, int histogram_id){ +riscvldhistrandom(Engine *E, State *S, int histogram_id) +{ Histogram_LDRandom(E, S, &S->riscv->histograms[histogram_id]); - + return; } -// Add two histograms +/* + * Add two histograms + */ void -riscvaddhist(Engine *E, State *S, int histogram_id0, int histogram_id1, int histogram_id_dest){ +riscvaddhist(Engine *E, State *S, int histogram_id0, int histogram_id1, int histogram_id_dest) +{ Histogram_AddDist( E, S, @@ -228,9 +284,12 @@ riscvaddhist(Engine *E, State *S, int histogram_id0, int histogram_id1, int hist return; } -// Scalar multiply a histogram +/* + * Scalar multiply a histogram + */ void -riscvscalarmultiply(Engine *E, State *S, int histogram_id0, int scalar){ +riscvscalarmultiply(Engine *E, State *S, int histogram_id0, int scalar) +{ Histogram_ScalarMultiply( E, S, @@ -241,7 +300,9 @@ riscvscalarmultiply(Engine *E, State *S, int histogram_id0, int scalar){ return; } -// Subtract two histograms +/* + * Subtract two histograms + */ void riscvsubhist(Engine *E, State *S, int histogram_id0, int histogram_id1, int histogram_id_dest){ Histogram_SubDist( @@ -256,9 +317,12 @@ riscvsubhist(Engine *E, State *S, int histogram_id0, int histogram_id1, int hist } -// Combine (bin-wise add) histograms +/* + * Combine (bin-wise add) histograms + */ void -riscvcombhist(Engine *E, State *S, int histogram_id0, int histogram_id1, int histogram_id_dest){ +riscvcombhist(Engine *E, State *S, int histogram_id0, int histogram_id1, int histogram_id_dest) +{ Histogram_CombDist( E, S, @@ -270,9 +334,12 @@ riscvcombhist(Engine *E, State *S, int histogram_id0, int histogram_id1, int his return; } -// Lower bound of histogram +/* + * Lower bound of histogram + */ void -riscvlowerboundhist(Engine *E, State *S, int histogram_id0, int output_reg){ +riscvlowerboundhist(Engine *E, State *S, int histogram_id0, int output_reg) +{ int result = Histogram_LowerBound( E, S, @@ -284,9 +351,12 @@ riscvlowerboundhist(Engine *E, State *S, int histogram_id0, int output_reg){ return; } -// Upper bound of histogram +/* + * Upper bound of histogram + */ void -riscvupperboundhist(Engine *E, State *S, int histogram_id0, int output_reg){ +riscvupperboundhist(Engine *E, State *S, int histogram_id0, int output_reg) +{ int result = Histogram_UpperBound( E, S, @@ -298,9 +368,12 @@ riscvupperboundhist(Engine *E, State *S, int histogram_id0, int output_reg){ return; } -// Left shift +/* + * Left shift + */ void -riscvdistlshifthist(Engine *E, State *S, int histogram_id0, int Rs2, int histogram_id_dest){ +riscvdistlshifthist(Engine *E, State *S, int histogram_id0, int Rs2, int histogram_id_dest) +{ Histogram_DistLShift( E, S, @@ -313,9 +386,12 @@ riscvdistlshifthist(Engine *E, State *S, int histogram_id0, int Rs2, int histogr } -// Right shift +/* + * Right shift + */ void -riscvdistrshifthist(Engine *E, State *S, int histogram_id0, int Rs2, int histogram_id_dest){ +riscvdistrshifthist(Engine *E, State *S, int histogram_id0, int Rs2, int histogram_id_dest) +{ Histogram_DistRShift( E, S, @@ -327,10 +403,12 @@ riscvdistrshifthist(Engine *E, State *S, int histogram_id0, int Rs2, int histogr return; } - -// Expected value +/* + * Expected value + */ void -riscvexpectedvaluehist(Engine *E, State *S, int histogram_id0, int output_reg){ +riscvexpectedvaluehist(Engine *E, State *S, int histogram_id0, int output_reg) +{ int result = Histogram_ExpectedValue( E, S, @@ -342,7 +420,9 @@ riscvexpectedvaluehist(Engine *E, State *S, int histogram_id0, int output_reg){ return; } -// DistLess returns the probability Pr(X < Rs2) +/* + * DistLess returns the probability Pr(X < Rs2) + */ void riscvdistlesshist(Engine *E, State *S, int histogram_id0, int Rs2, int output_reg){ int result = Histogram_DistLess( @@ -358,7 +438,9 @@ riscvdistlesshist(Engine *E, State *S, int histogram_id0, int Rs2, int output_re } -// DistGrt returns the probability Pr(X >= Rs2) +/* + * DistGrt returns the probability Pr(X >= Rs2) + */ void riscvdistgrthist(Engine *E, State *S, int histogram_id0, int Rs2, int output_reg){ int result = Histogram_DistGrt( @@ -373,28 +455,6 @@ riscvdistgrthist(Engine *E, State *S, int histogram_id0, int Rs2, int output_reg return; } - - - - - - - - - - - - - - - - - - - - - - static UncertainState * uncertainnewstate(Engine *E, char *ID) { @@ -416,7 +476,7 @@ uncertainnewstate(Engine *E, char *ID) State * riscvnewstate(Engine *E, double xloc, double yloc, double zloc, char *trajfilename) { - State *S = superHnewstate(E, xloc, yloc, zloc, trajfilename); + State * S = superHnewstate(E, xloc, yloc, zloc, trajfilename); S->riscv = (RiscvState *) mcalloc(E, 1, sizeof(RiscvState), "S->riscv"); if (S->riscv == NULL) @@ -432,7 +492,7 @@ riscvnewstate(Engine *E, double xloc, double yloc, double zloc, char *trajfilena S->flushpipe = riscvflushpipe; /* - * Histogram-specific menu items + * Histogram-specific menu items */ S->dumphist = riscvdumphist; S->dumphistpretty = riscvdumphistpretty; @@ -450,5 +510,3 @@ riscvnewstate(Engine *E, double xloc, double yloc, double zloc, char *trajfilena return S; } - - diff --git a/sim/machine-riscv.h b/sim/machine-riscv.h index c4d7ba82..583b71f7 100644 --- a/sim/machine-riscv.h +++ b/sim/machine-riscv.h @@ -35,28 +35,24 @@ POSSIBILITY OF SUCH DAMAGE. */ -struct RiscvState +typedef struct { - uint32_t R[RISCV_XMAX]; - uint64_t fR[RF32FD_fMAX]; - uint32_t fCSR; - RiscvPipe P; - UncertainState *uncertain; - uint32_t instruction_distribution[RISCV_OP_MAX]; + uint32_t R[RISCV_XMAX]; + uint64_t fR[RF32FD_fMAX]; + uint32_t fCSR; + RiscvPipe P; + UncertainState * uncertain; + uint32_t instruction_distribution[RISCV_OP_MAX]; /* * Taint analysis for registers (need last entry for PC's taint entry 32) */ - ShadowMem instruction_taintDistribution[RISCV_OP_MAX]; - ShadowMem taintR[RISCV_XMAX+1]; - ShadowMem taintfR[RF32FD_fMAX+1]; + ShadowMem instruction_taintDistribution[RISCV_OP_MAX]; + ShadowMem taintR[RISCV_XMAX+1]; + ShadowMem taintfR[RF32FD_fMAX+1]; /* - * Histograms + * Histograms */ - #define kMAX_NUM_HISTOGRAMS 10 - // This defines the subset of histogram-enabled registers. Set to RISCV_XMAX for having all (integer) registers having histograms associated with them - Histogram histograms[kMAX_NUM_HISTOGRAMS]; -}; - -typedef struct RiscvState RiscvState; + Histogram histograms[RISCV_XMAX]; +} RiscvState; diff --git a/sim/main.c b/sim/main.c index e29bb6d1..98c1d8f2 100755 --- a/sim/main.c +++ b/sim/main.c @@ -182,7 +182,7 @@ int main(int nargs, char *args[]) { Engine *E; - char *buf = NULL; + char *buf = NULL; int argn; @@ -267,8 +267,8 @@ sched_step(Engine *E) /* - TODO: make the locking finer grained, possibly also splitting out into reader and writer locks - */ + * TODO: make the locking finer grained, possibly also splitting out into reader and writer locks + */ mstatelock(); S = E->sp[E->cn]; min_secsleft = PICOSEC_MAX; @@ -485,12 +485,14 @@ updaterandsched(Engine *E) } } -fprintf(stderr, "sched:\t"); -for (i = 0; i < E->nnodes; i++) -{ - fprintf(stderr, "%d ", E->randsched[i]); -} -fprintf(stderr, "\n"); + /* + fprintf(stderr, "sched:\t"); + for (i = 0; i < E->nnodes; i++) + { + fprintf(stderr, "%d ", E->randsched[i]); + } + fprintf(stderr, "\n"); + */ } void @@ -779,11 +781,13 @@ loadcmds(Engine *E, char *filename) munchinput(E, buf); } - //streamchk(); - /* NOTE: scan_labels_and_globalvars does a sf_superh_parse(), so need yyengine set before */ + /* + * NOTE: scan_labels_and_globalvars does a sf_superh_parse(), so need yyengine set before + */ yyengine = E; + //streamchk(E); scan_labels_and_globalvars(E); - //streamchk(); + //streamchk(E); if (yyengine->cp->machinetype == MACHINE_SUPERH) { sf_superh_parse(); @@ -1004,33 +1008,38 @@ man(Engine *E, char *cmd) char * mstrsep(char **stringptr, const char *delim) { - char *s; - const char *spanp; - int c, sc; - char *tok; + char *s; + const char *spanp; + int c, sc; + char *tok; - if ((s = *stringptr) == NULL) + if ((s = *stringptr) == NULL) { - return NULL; + return NULL; } - for (tok = s;;) + for (tok = s;;) { - c = *s++; - spanp = delim; - do + c = *s++; + spanp = delim; + do { - if ((sc = *spanp++) == c) + if ((sc = *spanp++) == c) { - if (c == 0) - s = NULL; - else - s[-1] = 0; - *stringptr = s; - return (tok); - } - } while (sc != 0); - } + if (c == 0) + { + s = NULL; + } + else + { + s[-1] = 0; + } + *stringptr = s; + + return (tok); + } + } while (sc != 0); + } return NULL; } diff --git a/sim/main.h b/sim/main.h index bf4fd708..dff82808 100755 --- a/sim/main.h +++ b/sim/main.h @@ -98,6 +98,11 @@ #endif +/* + * NOTE: The code base currently violates our coding convention + * but this will be fixed soon. Some new constants (e.g., kUncertainAluHistogramBins) + * are defined according to the convention. + */ enum { DEFAULT_MEMREAD_LATENCY = 0, @@ -153,8 +158,6 @@ enum MAX_NUM_ENGINES = 4, MAX_BREAKPOINTS = 32, - - /* Keep sorted in order, so last entry is max */ MAX_NODESTDOUT_BUFSZ = 8192, MAX_NODESTDERR_BUFSZ = 8192, diff --git a/sim/mfns.h b/sim/mfns.h index 4e98e648..1f867f3e 100755 --- a/sim/mfns.h +++ b/sim/mfns.h @@ -711,9 +711,8 @@ void msp430_jl(Engine *E, State *S, short offset, MSP430Pipestage *p); void msp430_jmp(Engine *E, State *S, short offset, MSP430Pipestage *p); /* */ -/* RISC-V instruction functions */ +/* Microarchitecture and misc RISC-V functions */ /* */ - State* riscvnewstate(Engine *E, double xloc, double yloc, double zloc, char *trajfilename); void riscvstallaction(Engine *, State *S, ulong addr, int type, int latency); void riscvdumpregs(Engine *E, State *S); @@ -723,20 +722,16 @@ void riscvIFflush(State *S); void riscvIFIDflush(State *S); int riscvstep(Engine *E, State *S, int drain_pipe); int riscvfaststep(Engine *E, State *S, int drain_pipe); - -/* - * Histogram-specific functions - */ -// Print histogram -void riscvdumphist(Engine *E, State *S, int histogram_id); -// Pretty-print histogram distribution -void riscvdumphistpretty(Engine *E, State *S, int histogram_id); - -void riscvdumpdistribution(Engine *E, State *S); -void riscvdecode(Engine *E, uint32_t instr, RiscvPipestage *stage); +void riscvdumphist(Engine *E, State *S, int histogram_id); +void riscvdumphistpretty(Engine *E, State *S, int histogram_id); +void riscvdumpdistribution(Engine *E, State *S); +void riscvdecode(Engine *E, uint32_t instr, RiscvPipestage *stage); uint32_t reg_read_riscv(Engine *E, State *S, uint8_t n); void reg_set_riscv(Engine *E, State *S, uint8_t n, uint32_t data); +/* */ +/* RISC-V instruction functions */ +/* */ void riscv_nop(Engine *E, State *S); void riscv_add(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd); void riscv_sub(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd); @@ -787,12 +782,9 @@ void riscv_csrrwi(Engine *E, State *S); void riscv_csrrsi(Engine *E, State *S); void riscv_csrrci(Engine *E, State *S); - - /* */ -/* RISC-V RV32F additional functions */ +/* RISC-V RV32F additional functions */ /* */ - uint64_t freg_read_riscv(Engine *E, State *S, uint8_t n); void freg_set_riscv(Engine *E, State *S, uint8_t n, uint64_t data); void rv32f_flw(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0); @@ -822,12 +814,9 @@ void rv32f_fcvt_s_w(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd); void rv32f_fcvt_s_wu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd); void rv32f_fmv_w_x(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd); - - /* */ -/* RISC-V RV32D additional functions */ +/* RISC-V RV32D additional functions */ /* */ - void rv32d_fld(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0); void rv32d_fsd(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uint16_t imm5); void rv32d_fmadd_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd); @@ -855,15 +844,47 @@ void rv32d_fcvt_wu_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd); void rv32d_fcvt_d_w(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd); void rv32d_fcvt_d_wu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd); - - -/* */ +/* */ /* RISC-V uncertain additional functions */ -/* */ +/* */ void rv32un_unupg_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd); void rv32un_ungcov_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd); void rv32un_unsvar_s(Engine *E, State *S, uint8_t rs1, uint8_t _rs2, uint8_t rd); void rv32un_unclvar_s(Engine *E, State *S, uint8_t _rs1, uint8_t _rs2, uint8_t rd); void rv32un_uncpvar_s(Engine *E, State *S, uint8_t _rs1, uint8_t _rs2, uint8_t rd); - void rv32un_un_part1(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0); + + +/* + * Histogram arithmetic. + */ +void Histogram_AddDist(Engine *E, State *S, Histogram *hist1, Histogram *hist2, Histogram *histDest); +void Histogram_ScalarMultiply(Engine *E, State *S, Histogram *hist, HistogramBinDatatype scalar); +void Histogram_SubDist(Engine *E, State *S, Histogram *hist1, Histogram *hist2, Histogram *histDest); +void Histogram_CombDist(Engine *E, State *S, Histogram *hist1, Histogram *hist2, Histogram *histDest); +int Histogram_LowerBound(Engine *E, State *S, Histogram *hist); +int Histogram_UpperBound(Engine *E, State *S, Histogram *hist); +void Histogram_DistLShift(Engine *E, State *S, Histogram *hist1, uint8_t Rs2, Histogram *histDest); +void Histogram_DistRShift(Engine *E, State *S, Histogram *hist1, uint8_t Rs2, Histogram *histDest); +uint8_t Histogram_ExpectedValue(Engine *E, State *S, Histogram *hist); +uint32_t Histogram_DistLess(Engine *E, State *S, Histogram *hist, uint32_t Rs2); +uint32_t Histogram_DistGrt(Engine *E, State *S, Histogram *hist, uint32_t Rs2); +void Histogram_LDDist(Engine *E, State *S, Histogram *histogram, HistogramBinDatatype bins[kUncertainAluHistogramBins]); +void Histogram_LDRandom(Engine *E, State *S, Histogram *histogram); +double Histogram_Mean(Engine *E, State *S, Histogram *histogram); +void Histogram_PrettyPrint(Engine *E, State *S, Histogram *histogram); +double Histogram_MeanFrequency(Engine *E, State *S, Histogram *histogram); + +/* + * Uncertainty propagation equation arithmetic + */ +int uncertain_print_system(UncertainState * state, FILE *stream); +void uncertain_sizemen(Engine *E, State *S, int size); +void uncertain_inst_lr(UncertainState * state, int ud, int location); +void uncertain_inst_sr(UncertainState * state, int us1, int location); +void uncertain_inst_mv(UncertainState * state, int ud, int us1); +void uncertain_inst_up1(UncertainState * state, int ud, int us1, float g1); +void uncertain_inst_up2(UncertainState * state, int ud, int us1, int us2, float g1, float g2); +float uncertain_inst_gv(UncertainState * state, int us1); +float uncertain_inst_gcov(UncertainState * state, int us1, int us2); +void uncertain_inst_sv(UncertainState * state, int ud, float variance); diff --git a/sim/mkdecode-hitachi-sh b/sim/mkdecode-hitachi-sh index 758ff54d..8d3477d2 100755 --- a/sim/mkdecode-hitachi-sh +++ b/sim/mkdecode-hitachi-sh @@ -6,7 +6,7 @@ fi - echo '/* This is dependent on latencies-hitachi-sh.h */' + echo '/* DO NOTE EDIT! This file is auto-generated from latencies-hitachi-sh.h */' echo 'enum' echo '{' cat latencies-hitachi-sh.h | grep _OP_ | sed "s/.*\[\(SUPERH_OP_.*[A-Z0-9]\)\].*/\1,/" | sed "s/^\(.*MAX,\)/MAX~\1/" | $1 -F'~' '{if($1=="MAX"){print "\n\t"$2"\n"}else{print "\t"$1}}' diff --git a/sim/mkdecode-riscv b/sim/mkdecode-riscv index ba37d7e9..0b95c74f 100755 --- a/sim/mkdecode-riscv +++ b/sim/mkdecode-riscv @@ -6,7 +6,7 @@ fi - echo '/* This is dependent on latencies-riscv.h */' + echo '/* DO NOTE EDIT! This file is auto-generated from latencies-riscv.h. */' echo 'enum' echo '{' cat latencies-riscv.h | grep _OP_ | sed "s/.*\[\(R.*_OP_.*[A-Z0-9]\)\].*/\1,/" | sed "s/^\(.*MAX,\)/MAX~\1/" | $1 -F'~' '{if($1=="MAX"){print "\n\t"$2"\n"}else{print "\t"$1}}' diff --git a/sim/mkopstr-riscv b/sim/mkopstr-riscv index 4dfb8bc5..cd02af34 100755 --- a/sim/mkopstr-riscv +++ b/sim/mkopstr-riscv @@ -9,5 +9,5 @@ echo 'char *riscv_opstrs[] =\' echo '{' - cat decode-riscv.h | sed "s/_OP_/~OP~/g" | grep OP | sed "s/.*RISCV~/RISCV~/g" | sed "s/.*RV/RV/g" | $1 -F',|~' '{print "\t["$1"_"$2"_"$3"]\t\t\""$3"\","}' + cat decode-riscv.h | grep '_OP_' | sed "s/_OP_/~OP~/g" | grep OP | sed "s/.*RISCV~/RISCV~/g" | sed "s/.*RV/RV/g" | $1 -F',|~' '{print "\t["$1"_"$2"_"$3"]\t\t\""$3"\","}' echo '};' diff --git a/sim/op-riscv.c b/sim/op-riscv.c index 22b69818..05c7fa25 100644 --- a/sim/op-riscv.c +++ b/sim/op-riscv.c @@ -1,6 +1,6 @@ /* Copyright (c) 2017-2018, Zhengyang Gu (author) - 2019, Hein Alexander Mante (author) + 2019, Hein Alexander Mante (taint propagation) All rights reserved. @@ -44,17 +44,18 @@ #include "instr-riscv.h" #include "mextern.h" -uint32_t sign_extend(uint32_t data, uint8_t n) +uint32_t +sign_extend(uint32_t data, uint8_t n) { - uint32_t sign_mask = 1 << (n-1); - uint32_t valid_bits; + uint32_t sign_mask = 1 << (n-1); + uint32_t valid_bits; if (n == 32) { valid_bits = -1; } else { - valid_bits = (1 << n) - 1; + valid_bits = (1 << n) - 1; } if (data & sign_mask) { @@ -67,43 +68,48 @@ uint32_t sign_extend(uint32_t data, uint8_t n) } } -/* Convert a 32 bit (single precision) float into a NaN 64 bit - * (double precision) float containing the single precision - * float in the lower 32 bits. +/* + * Convert a 32 bit (single precision) float into a NaN 64 bit + * (double precision) float containing the single precision + * float in the lower 32 bits. */ -uint64_t nan_box(uint32_t f) +uint64_t +nan_box(uint32_t f) { return ((~(uint64_t)0) << 32) | f; } -/* Checks if a 64-bit value is NaN-boxed - * returns the lower 32-bits if NaN-boxed and a canonical NaN if otherwise +/* + * Checks if a 64-bit value is NaN-boxed + * returns the lower 32-bits if NaN-boxed and a canonical NaN if otherwise */ -uint32_t is_nan_boxed(uint64_t f) +uint32_t +is_nan_boxed(uint64_t f) { if((uint32_t)(f >> 32) == 0xFFFFFFFF) return (uint32_t)f; else return 0x7FFFFFFF; } -void riscv_nop(Engine *E, State *S)/* pseudo instruction */ +void +riscv_nop(Engine *E, State *S)/* pseudo instruction */ { riscv_addi(E, S, 0, 0, 0); return; } -int get_uncertain_memory_index(Engine *E, State *S, uint32_t vaddr) +int get_uncertain_memory_index(Engine *E, State *S, uint32_t vaddr) { /* TODO: programmatically pick a sensible value * Note that in the "finished" version uncertain memory will be * indexed starting at zero and so this will not be needed. */ - const uint32_t INST_END_ADDR = 0x8009fa4; + const uint32_t INST_END_ADDR = 0x8009fa4; if ((vaddr & 0b11) != 0) { - merror(E, "Unaligned uncertain aware floating point load/store at address 0x%08u", vaddr); + merror(E, "Unaligned uncertain aware floating point load/store at address 0x%08u", vaddr); } - int addr = (int)(vaddr - INST_END_ADDR) / 4; + int addr = (int)(vaddr - INST_END_ADDR) / 4; return addr; } @@ -122,11 +128,11 @@ void uncertain_check_part2_pc(Engine *E, State *S) tmp->op_fp_pc, S->riscv->P.EX.fetchedpc ); - } } -void riscv_add(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +riscv_add(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { reg_set_riscv(E, S, rd, (reg_read_riscv(E, S, rs1) + reg_read_riscv(E, S, rs2))); @@ -139,7 +145,8 @@ void riscv_add(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) return; } -void riscv_sub(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +riscv_sub(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { reg_set_riscv(E, S, rd, (reg_read_riscv(E, S, rs1) - reg_read_riscv(E, S, rs2))); @@ -147,16 +154,14 @@ void riscv_sub(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_slt(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +riscv_slt(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - if ((int32_t) reg_read_riscv(E, S, rs1) < (int32_t) reg_read_riscv(E, S, rs2)) { reg_set_riscv(E, S, rd, 1); @@ -165,22 +170,20 @@ void riscv_slt(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { reg_set_riscv(E, S, rd, 0); } - + if (SF_TAINTANALYSIS) { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_sltu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +riscv_sltu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - if (reg_read_riscv(E, S, rs1) < reg_read_riscv(E, S, rs2)) { reg_set_riscv(E, S, rd, 1); @@ -193,15 +196,14 @@ void riscv_sltu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_and(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +riscv_and(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { reg_set_riscv(E, S, rd, (reg_read_riscv(E, S, rs1) & reg_read_riscv(E, S, rs2))); @@ -209,14 +211,13 @@ void riscv_and(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_or(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +riscv_or(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { reg_set_riscv(E, S, rd, (reg_read_riscv(E, S, rs1) | reg_read_riscv(E, S, rs2))); @@ -224,14 +225,13 @@ void riscv_or(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_xor(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +riscv_xor(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { reg_set_riscv(E, S, rd, (reg_read_riscv(E, S, rs1) ^ reg_read_riscv(E, S, rs2))); @@ -239,73 +239,72 @@ void riscv_xor(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_sll(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +riscv_sll(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - int xlen_b = 5; - int mask = ((1 << xlen_b) - 1); - uint8_t shift = reg_read_riscv(E, S, rs2) & mask; + int xlen_b = 5; + int mask = ((1 << xlen_b) - 1); + uint8_t shift = reg_read_riscv(E, S, rs2) & mask; + reg_set_riscv(E, S, rd, (reg_read_riscv(E, S, rs1) << shift)); if (SF_TAINTANALYSIS) { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_srl(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +riscv_srl(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - int xlen_b = 5; - int mask = ((1 << xlen_b) - 1); - uint8_t shift = reg_read_riscv(E, S, rs2) & mask; + int xlen_b = 5; + int mask = ((1 << xlen_b) - 1); + uint8_t shift = reg_read_riscv(E, S, rs2) & mask; + reg_set_riscv(E, S, rd, (reg_read_riscv(E, S, rs1) >> shift)); if (SF_TAINTANALYSIS) { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_sra(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +riscv_sra(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - int xlen_b = 5; - int mask = ((1 << xlen_b) - 1); - uint8_t shift = reg_read_riscv(E, S, rs2) & mask; - uint32_t data = ((signed int) reg_read_riscv(E, S, rs1)) >> shift; + int xlen_b = 5; + int mask = ((1 << xlen_b) - 1); + uint8_t shift = reg_read_riscv(E, S, rs2) & mask; + uint32_t data = ((signed int) reg_read_riscv(E, S, rs1)) >> shift; + reg_set_riscv(E, S, rd, data); if (SF_TAINTANALYSIS) { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_addi(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) +void +riscv_addi(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { /* - * Assumption: imm0 carries no taint (assumption carries on to all other functions - * with immediate values but will only be stated here) - */ + * Assumption: imm0 carries no taint (assumption carries on to all other functions + * with immediate values but will only be stated here) + */ reg_set_riscv(E, S, rd, (reg_read_riscv(E, S, rs1) + (int32_t) sign_extend(imm0, 12))); @@ -313,13 +312,12 @@ void riscv_addi(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_slti(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) +void +riscv_slti(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { if ((int32_t) reg_read_riscv(E, S, rs1) < (int32_t) sign_extend(imm0, 12)) { @@ -334,14 +332,13 @@ void riscv_slti(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_sltiu(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) +void +riscv_sltiu(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { if (reg_read_riscv(E, S, rs1) < sign_extend(imm0, 12)) { @@ -356,14 +353,13 @@ void riscv_sltiu(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_andi(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) +void +riscv_andi(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { reg_set_riscv(E, S, rd, (reg_read_riscv(E, S, rs1) & sign_extend(imm0, 12))); @@ -371,14 +367,13 @@ void riscv_andi(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_ori(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) +void +riscv_ori(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { reg_set_riscv(E, S, rd, (reg_read_riscv(E, S, rs1) | sign_extend(imm0, 12))); @@ -386,14 +381,13 @@ void riscv_ori(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_xori(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) +void +riscv_xori(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { reg_set_riscv(E, S, rd, (reg_read_riscv(E, S, rs1) ^ sign_extend(imm0, 12))); @@ -401,17 +395,16 @@ void riscv_xori(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_slli(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) +void +riscv_slli(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { - int xlen_b = 5; - int mask = ((1 << xlen_b) - 1); + int xlen_b = 5; + int mask = ((1 << xlen_b) - 1); uint8_t shift = imm0 & mask; reg_set_riscv(E, S, rd, (reg_read_riscv(E, S, rs1) << shift)); @@ -420,17 +413,16 @@ void riscv_slli(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_srli(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) +void +riscv_srli(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { - int xlen_b = 5; - int mask = ((1 << xlen_b) - 1); + int xlen_b = 5; + int mask = ((1 << xlen_b) - 1); uint8_t shift = imm0 & mask; reg_set_riscv(E, S, rd, (reg_read_riscv(E, S, rs1) >> shift)); @@ -439,58 +431,56 @@ void riscv_srli(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_srai(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) +void +riscv_srai(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint32_t imm0) { - int xlen_b = 5; - int mask = ((1 << xlen_b) - 1); + int xlen_b = 5; + int mask = ((1 << xlen_b) - 1); uint8_t shift = imm0 & mask; - uint32_t data = ((signed int)reg_read_riscv(E, S, rs1)) >> shift; + uint32_t data = ((signed int)reg_read_riscv(E, S, rs1)) >> shift; reg_set_riscv(E, S, rd, data); if (SF_TAINTANALYSIS) { taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_lui(Engine *E, State *S, uint8_t rd, uint32_t imm0) +void +riscv_lui(Engine *E, State *S, uint8_t rd, uint32_t imm0) { reg_set_riscv(E, S, rd, (imm0<<12)); return; } -void riscv_auipc(Engine *E, State *S, uint8_t rd, uint32_t imm0) +void +riscv_auipc(Engine *E, State *S, uint8_t rd, uint32_t imm0) { reg_set_riscv(E, S, rd, (imm0<<12) + S->PC - 4); if (SF_TAINTANALYSIS) { /* - * Propagate taint of PC into register[rd]: - */ + * Propagate taint of PC into register[rd]: + */ taintprop(E, S, taintretreg(E,S,32), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_jal(Engine *E, State *S, uint8_t rd, uint16_t imm1, uint8_t imm11, uint8_t imm12, uint8_t imm20) +void +riscv_jal(Engine *E, State *S, uint8_t rd, uint16_t imm1, uint8_t imm11, uint8_t imm12, uint8_t imm20) { int32_t offset = sign_extend((imm1 << 1) + (imm11 << 11) + (imm12 << 12) + (imm20 << 20), 21); @@ -503,22 +493,21 @@ void riscv_jal(Engine *E, State *S, uint8_t rd, uint16_t imm1, uint8_t imm11, ui (uint64_t)rd, kSunflowerTaintMemTypeRegister); /* - * If immediates are seen as carrying taint, more then their taint - * should also be propagated to the PC (ORed with the PC's previous - * taint). - */ - - + * If immediates are seen as carrying taint, more then their taint + * should also be propagated to the PC (ORed with the PC's previous + * taint). + */ } return; } -void riscv_jalr(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) +void +riscv_jalr(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) { int32_t addr = (int32_t) sign_extend(imm0, 12) + (int32_t) reg_read_riscv(E, S, rs1); - uint32_t mask = -2; + uint32_t mask = -2; reg_set_riscv(E, S, rd, S->PC); S->PC = (addr) & mask; @@ -530,14 +519,13 @@ void riscv_jalr(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)32, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_beq(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint8_t imm5,\ +void +riscv_beq(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint8_t imm5,\ uint8_t imm11, uint8_t imm12) { if (reg_read_riscv(E, S, rs1) == reg_read_riscv(E, S, rs2)) @@ -551,12 +539,12 @@ void riscv_beq(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)32, kSunflowerTaintMemTypeRegister); - } return; } -void riscv_bne(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint8_t imm5,\ +void +riscv_bne(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint8_t imm5,\ uint8_t imm11, uint8_t imm12) { @@ -571,13 +559,13 @@ void riscv_bne(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)32, kSunflowerTaintMemTypeRegister); - } return; } -void riscv_blt(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint8_t imm5,\ +void +riscv_blt(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint8_t imm5,\ uint8_t imm11, uint8_t imm12) { if ((int32_t) reg_read_riscv(E, S, rs1) < (int32_t) reg_read_riscv(E, S, rs2)) @@ -591,14 +579,13 @@ void riscv_blt(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)32, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_bltu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint8_t imm5,\ +void +riscv_bltu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint8_t imm5,\ uint8_t imm11, uint8_t imm12) { if (reg_read_riscv(E, S, rs1) < reg_read_riscv(E, S, rs2)) @@ -612,13 +599,12 @@ void riscv_bltu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uin { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)32, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_bge(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint8_t imm5,\ +void +riscv_bge(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint8_t imm5,\ uint8_t imm11, uint8_t imm12) { if ((int32_t) reg_read_riscv(E, S, rs1) >= (int32_t) reg_read_riscv(E, S, rs2)) @@ -632,14 +618,13 @@ void riscv_bge(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)32, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_bgeu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint8_t imm5,\ +void +riscv_bgeu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uint8_t imm5,\ uint8_t imm11, uint8_t imm12) { if (reg_read_riscv(E, S, rs1) >= reg_read_riscv(E, S, rs2)) @@ -653,18 +638,17 @@ void riscv_bgeu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t imm1, uin { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)32, kSunflowerTaintMemTypeRegister); - - } return; } -void riscv_lw(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) +void +riscv_lw(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) { - uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0, 12); + uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0, 12); - uint32_t value = superHreadlong(E, S, addr); + uint32_t value = superHreadlong(E, S, addr); reg_set_riscv(E, S, rd, value); @@ -677,9 +661,10 @@ void riscv_lw(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) return; } -void riscv_lh(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) +void +riscv_lh(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) { - uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0, 12); + uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0, 12); reg_set_riscv(E, S, rd, sign_extend(superHreadword(E, S, addr), 16)); @@ -687,15 +672,15 @@ void riscv_lh(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) { taintprop(E, S, taintretreg(E,S,rs1), taintretmems(E,S,addr,2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void riscv_lhu(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) +void +riscv_lhu(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) { - uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0, 12); + uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0, 12); reg_set_riscv(E, S, rd, (uint32_t) superHreadword(E, S, addr)); @@ -703,17 +688,16 @@ void riscv_lhu(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) { taintprop(E, S, taintretreg(E,S,rs1), taintretmems(E,S,addr,2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void riscv_lb(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) +void +riscv_lb(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) { - uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0, 12); - - uint8_t data_b = superHreadword(E, S, addr) & 0xff; + uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0, 12); + uint8_t data_b = superHreadword(E, S, addr) & 0xff; reg_set_riscv(E, S, rd, sign_extend(data_b, 8)); @@ -721,17 +705,16 @@ void riscv_lb(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) { taintprop(E, S, taintretreg(E,S,rs1), taintretmems(E,S,addr,1), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void riscv_lbu(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) +void +riscv_lbu(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) { - uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0, 12); - - uint8_t data_b = superHreadword(E, S, addr) & 0xff; + uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0, 12); + uint8_t data_b = superHreadword(E, S, addr) & 0xff; reg_set_riscv(E, S, rd, (uint32_t) data_b); @@ -739,51 +722,50 @@ void riscv_lbu(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) { taintprop(E, S, taintretreg(E,S,rs1), taintretmems(E,S,addr,1), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void riscv_sw(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uint16_t imm5) +void +riscv_sw(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uint16_t imm5) { - uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0 + (imm5 << 5), 12); - - uint32_t value = reg_read_riscv(E,S, rs2); + uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0 + (imm5 << 5), 12); + uint32_t value = reg_read_riscv(E,S, rs2); superHwritelong(E, S, addr, value); if (SF_TAINTANALYSIS) { - for (int i = 0 ; i<4 ; i++) + for (int i = 0 ; i<4 ; i++) { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)(addr+i), kSunflowerTaintMemTypeMemory); } - } } -void riscv_sh(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uint16_t imm5) +void +riscv_sh(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uint16_t imm5) { - uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0 + (imm5 << 5), 12); + uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0 + (imm5 << 5), 12); superHwriteword(E, S,addr, reg_read_riscv(E,S, rs2) & 0xffff); if (SF_TAINTANALYSIS) { - for (int i = 0 ; i<2 ; i++) + for (int i = 0 ; i<2 ; i++) { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)(addr+i), kSunflowerTaintMemTypeMemory); } - } } -void riscv_sb(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uint16_t imm5) +void +riscv_sb(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uint16_t imm5) { - uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0 + (imm5 << 5), 12); + uint32_t addr = reg_read_riscv(E,S, rs1) + sign_extend(imm0 + (imm5 << 5), 12); superHwritebyte(E, S,addr, reg_read_riscv(E,S, rs2) & 0xff); @@ -791,40 +773,102 @@ void riscv_sb(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uint { taintprop(E, S, taintretreg(E,S,rs1), taintretreg(E,S,rs2), (uint64_t)addr, kSunflowerTaintMemTypeMemory); - } } -void riscv_fence(Engine *E, State *S) {} -void riscv_fence_i(Engine *E, State *S) {} -void riscv_cor(Engine *E, State *S) {} -void riscv_ebreak(Engine *E, State *S) {} -void riscv_csrrw(Engine *E, State *S) {} -void riscv_csrrs(Engine *E, State *S) {} -void riscv_csrrc(Engine *E, State *S) {} -void riscv_csrrwi(Engine *E, State *S) {} -void riscv_csrrsi(Engine *E, State *S) {} -void riscv_csrrci(Engine *E, State *S) {} +void +riscv_fence(Engine *E, State *S) +{ + return; +} + +void +riscv_fence_i(Engine *E, State *S) +{ + return; +} + +void +riscv_cor(Engine *E, State *S) +{ + return; +} + +void +riscv_ebreak(Engine *E, State *S) +{ + return; +} + +void +riscv_csrrw(Engine *E, State *S) +{ + return; +} + +void +riscv_csrrs(Engine *E, State *S) +{ + return; +} + +void +riscv_csrrc(Engine *E, State *S) +{ + return; +} + +void +riscv_csrrwi(Engine *E, State *S) +{ + return; +} + +void +riscv_csrrsi(Engine *E, State *S) +{ + return; +} + +void +riscv_csrrci(Engine *E, State *S) +{ + return; +} + +void +riscv_ecall(Engine *E, State *S) +{ + /* + * http://man7.org/linux/man-pages/man2/syscall.2.html + */ + uint32_t syscall_num = reg_read_riscv(E, S, RISCV_A7); -void riscv_ecall(Engine *E, State *S) { - // http://man7.org/linux/man-pages/man2/syscall.2.html - uint32_t syscall_num = reg_read_riscv(E, S, RISCV_A7); riscv_sim_syscall(E, S, syscall_num, reg_read_riscv(E, S, RISCV_A0), reg_read_riscv(E, S, RISCV_A1), reg_read_riscv(E, S, RISCV_A2)); /* - * No taint propagation implemented in this function - */ + * No taint propagation implemented in this function + */ } -/* RISC-V RV32F instructions */ -void rv32f_flw(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) + +/* + * RISC-V RV32F instructions + */ + + + +void +rv32f_flw(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) { - uint32_t addr = reg_read_riscv(E, S, rs1) + sign_extend(imm0, 12); + uint32_t addr = reg_read_riscv(E, S, rs1) + sign_extend(imm0, 12); - // Perform a normal floating point load. + /* + * Perform a normal floating point load. + */ freg_set_riscv(E, S, rd, nan_box(superHreadlong(E, S, addr))); if (SF_TAINTANALYSIS) @@ -839,17 +883,17 @@ void rv32f_flw(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) { uncertain_check_part2_pc(E, S); - uint32_t rs1Uncertain = ((instr_i *)&S->riscv->uncertain->last_op.insn_part1)->rs1; - uint32_t immUncertain = ((instr_i *)&S->riscv->uncertain->last_op.insn_part1)->imm0; + uint32_t rs1Uncertain = ((instr_i *)&S->riscv->uncertain->last_op.insn_part1)->rs1; + uint32_t immUncertain = ((instr_i *)&S->riscv->uncertain->last_op.insn_part1)->imm0; - uint32_t uncertainAddr = reg_read_riscv(E, S, rs1Uncertain) + sign_extend(immUncertain, 12); - int uncertainIndex = get_uncertain_memory_index(E, S, uncertainAddr); + uint32_t uncertainAddr = reg_read_riscv(E, S, rs1Uncertain) + sign_extend(immUncertain, 12); + int uncertainIndex = get_uncertain_memory_index(E, S, uncertainAddr); /* - * If the uncertainIndex is negative then we are trying to read a memory location - * in the `.text` section of the binary. This is how gnu generated binaries initialise - * floats. For now, just load an uncertainty of zero. - */ + * If the uncertainIndex is negative then we are trying to read a memory location + * in the `.text` section of the binary. This is how gnu generated binaries initialise + * floats. For now, just load an uncertainty of zero. + */ if (uncertainIndex < 0) uncertain_inst_sv(S->riscv->uncertain, rd, 0); else @@ -861,16 +905,19 @@ void rv32f_flw(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) return; } -void rv32f_fsw(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uint16_t imm5) +void +rv32f_fsw(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uint16_t imm5) { - uint32_t addr = reg_read_riscv(E, S, rs1) + sign_extend(imm0 + (imm5 << 5), 12); + uint32_t addr = reg_read_riscv(E, S, rs1) + sign_extend(imm0 + (imm5 << 5), 12); - // Perform a normal floating point store. + /* + * Perform a normal floating point store. + */ superHwritelong(E, S, addr, freg_read_riscv(E, S, rs2)); if (SF_TAINTANALYSIS) { - for (int i = 0 ; i<4 ; i++) + for (int i = 0 ; i<4 ; i++) { taintprop(E, S, taintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)(addr+i), kSunflowerTaintMemTypeMemory); @@ -883,26 +930,27 @@ void rv32f_fsw(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uin { uncertain_check_part2_pc(E, S); - uint32_t rs1Uncertain = ((instr_i *)&S->riscv->uncertain->last_op.insn_part1)->rs1; - uint32_t immUncertain = ((instr_i *)&S->riscv->uncertain->last_op.insn_part1)->imm0; - - uint32_t uncertainAddr = reg_read_riscv(E, S, rs1Uncertain) + sign_extend(immUncertain, 12); - int uncertainIndex = get_uncertain_memory_index(E, S, uncertainAddr); + uint32_t rs1Uncertain = ((instr_i *)&S->riscv->uncertain->last_op.insn_part1)->rs1; + uint32_t immUncertain = ((instr_i *)&S->riscv->uncertain->last_op.insn_part1)->imm0; + uint32_t uncertainAddr = reg_read_riscv(E, S, rs1Uncertain) + sign_extend(immUncertain, 12); + int uncertainIndex = get_uncertain_memory_index(E, S, uncertainAddr); /* - * If software tries to store an uncertain value into the `.text` section - * I think it is a bug in that software(?). - * - * Regardless, the uncertain memory does not exist for negative indexes so - * we cannot possibly fulfill this store. Instead, log an error. - */ + * If software tries to store an uncertain value into the `.text` section + * I think it is a bug in that software(?). + * + * Regardless, the uncertain memory does not exist for negative indexes so + * we cannot possibly fulfill this store. Instead, log an error. + */ if (uncertainIndex < 0) { merror(E, "Cannot store uncertainty to address %X.\n", uncertainAddr); - } else { - + } + else + { uncertain_inst_sr(S->riscv->uncertain, rs2, uncertainIndex); } + S->riscv->uncertain->last_op.valid = 0; } } @@ -910,9 +958,10 @@ void rv32f_fsw(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uin return; } -void rv32f_fmadd_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) +void +rv32f_fmadd_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) { - rv32f_rep src1, src2, src3, result; + rv32f_rep src1, src2, src3, result; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); src2.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs2)); @@ -922,7 +971,6 @@ void rv32f_fmadd_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, u switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, nan_box(result.bit_value)); @@ -936,9 +984,10 @@ void rv32f_fmadd_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, u return; } -void rv32f_fmsub_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) +void +rv32f_fmsub_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) { - rv32f_rep src1, src2, src3, result; + rv32f_rep src1, src2, src3, result; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); src2.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs2)); @@ -948,7 +997,6 @@ void rv32f_fmsub_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, u switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, nan_box(result.bit_value)); @@ -957,15 +1005,15 @@ void rv32f_fmsub_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, u { taintprop(E, S, ftaintretreg(E,S,rs1), (ftaintretreg(E,S,rs2) | ftaintretreg(E,S,rs3)), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32f_fnmsub_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) +void +rv32f_fnmsub_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) { - rv32f_rep src1, src2, src3, result; + rv32f_rep src1, src2, src3, result; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); src2.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs2)); @@ -975,7 +1023,6 @@ void rv32f_fnmsub_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, nan_box(result.bit_value)); @@ -984,15 +1031,15 @@ void rv32f_fnmsub_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, { taintprop(E, S, ftaintretreg(E,S,rs1), (ftaintretreg(E,S,rs2) | ftaintretreg(E,S,rs3)), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32f_fnmadd_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) +void +rv32f_fnmadd_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) { - rv32f_rep src1, src2, src3, result; + rv32f_rep src1, src2, src3, result; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); src2.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs2)); @@ -1002,7 +1049,6 @@ void rv32f_fnmadd_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, nan_box(result.bit_value)); @@ -1011,17 +1057,16 @@ void rv32f_fnmadd_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, { taintprop(E, S, ftaintretreg(E,S,rs1), (ftaintretreg(E,S,rs2) | ftaintretreg(E,S,rs3)), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32f_fadd_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fadd_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; - - rv32f_rep src1, src2, result; + uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; + rv32f_rep src1, src2, result; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); src2.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs2)); @@ -1030,7 +1075,6 @@ void rv32f_fadd_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, nan_box(result.bit_value)); @@ -1039,7 +1083,6 @@ void rv32f_fadd_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } if (S->riscv->uncertain != NULL && S->riscv->uncertain->last_op.valid) @@ -1053,11 +1096,11 @@ void rv32f_fadd_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) return; } -void rv32f_fsub_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fsub_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; - - rv32f_rep src1, src2, result; + uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; + rv32f_rep src1, src2, result; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); src2.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs2)); @@ -1066,7 +1109,6 @@ void rv32f_fsub_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, nan_box(result.bit_value)); @@ -1075,7 +1117,6 @@ void rv32f_fsub_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } if (S->riscv->uncertain != NULL && S->riscv->uncertain->last_op.valid) @@ -1089,12 +1130,11 @@ void rv32f_fsub_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) return; } -void rv32f_fmul_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fmul_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - - uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; - - rv32f_rep src1, src2, result; + uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; + rv32f_rep src1, src2, result; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); src2.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs2)); @@ -1103,7 +1143,6 @@ void rv32f_fmul_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, nan_box(result.bit_value)); @@ -1112,13 +1151,11 @@ void rv32f_fmul_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } if (S->riscv->uncertain != NULL && S->riscv->uncertain->last_op.valid) { uncertain_check_part2_pc(E, S); - uncertain_inst_up2(S->riscv->uncertain, rd, rs1, rs2, src2.float_value, src1.float_value); S->riscv->uncertain->last_op.valid = 0; } @@ -1126,24 +1163,23 @@ void rv32f_fmul_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) return; } -void rv32f_fdiv_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fdiv_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; - - rv32f_rep src1, src2, result; + uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; + rv32f_rep src1, src2, result; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); src2.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs2)); - float divsrc2 = 1 / src2.float_value; - float src1div2 = src1.float_value * divsrc2; - float minussrc1div2div2 = -src1div2 / src2.float_value; + float divsrc2 = 1 / src2.float_value; + float src1div2 = src1.float_value * divsrc2; + float minussrc1div2div2 = -src1div2 / src2.float_value; result.float_value = src1div2; switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, nan_box(result.bit_value)); @@ -1152,13 +1188,11 @@ void rv32f_fdiv_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } if (S->riscv->uncertain != NULL && S->riscv->uncertain->last_op.valid) { uncertain_check_part2_pc(E, S); - uncertain_inst_up2(S->riscv->uncertain, rd, rs1, rs2, divsrc2, minussrc1div2div2); S->riscv->uncertain->last_op.valid = 0; } @@ -1166,21 +1200,20 @@ void rv32f_fdiv_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) return; } -void rv32f_fsqrt_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fsqrt_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; - - rv32f_rep src1, result; + uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; + rv32f_rep src1, result; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); - float root = sqrtf(src1.float_value); + float root = sqrtf(src1.float_value); result.float_value = root; switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, nan_box(result.bit_value)); @@ -1189,13 +1222,11 @@ void rv32f_fsqrt_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } if (S->riscv->uncertain != NULL && S->riscv->uncertain->last_op.valid) { uncertain_check_part2_pc(E, S); - uncertain_inst_up1(S->riscv->uncertain, rd, rs1, 0.5 / root); S->riscv->uncertain->last_op.valid = 0; } @@ -1203,12 +1234,12 @@ void rv32f_fsqrt_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) return; } -void rv32f_fsgnj_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fsgnj_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - uint32_t src1 = is_nan_boxed(freg_read_riscv(E, S, rs1)); - uint32_t src2 = is_nan_boxed(freg_read_riscv(E, S, rs2)); - - uint32_t result = (src1 & (-1 - (1 << 31))) | (src2 & (1 << 31)); + uint32_t src1 = is_nan_boxed(freg_read_riscv(E, S, rs1)); + uint32_t src2 = is_nan_boxed(freg_read_riscv(E, S, rs2)); + uint32_t result = (src1 & (-1 - (1 << 31))) | (src2 & (1 << 31)); freg_set_riscv(E, S, rd, nan_box(result)); @@ -1216,13 +1247,11 @@ void rv32f_fsgnj_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } if (S->riscv->uncertain != NULL && S->riscv->uncertain->last_op.valid) { uncertain_check_part2_pc(E, S); - uncertain_inst_mv(S->riscv->uncertain, rd, rs1); S->riscv->uncertain->last_op.valid = 0; } @@ -1230,12 +1259,12 @@ void rv32f_fsgnj_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) return; } -void rv32f_fsgnjn_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fsgnjn_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - uint32_t src1 = is_nan_boxed(freg_read_riscv(E, S, rs1)); - uint32_t src2 = is_nan_boxed(freg_read_riscv(E, S, rs2)); - - uint32_t result = (src1 & (-1 - (1 << 31))) | (~src2 & (1 << 31)); + uint32_t src1 = is_nan_boxed(freg_read_riscv(E, S, rs1)); + uint32_t src2 = is_nan_boxed(freg_read_riscv(E, S, rs2)); + uint32_t result = (src1 & (-1 - (1 << 31))) | (~src2 & (1 << 31)); freg_set_riscv(E, S, rd, nan_box(result)); @@ -1243,13 +1272,11 @@ void rv32f_fsgnjn_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } if (S->riscv->uncertain != NULL && S->riscv->uncertain->last_op.valid) { uncertain_check_part2_pc(E, S); - uncertain_inst_mv(S->riscv->uncertain, rd, rs1); S->riscv->uncertain->last_op.valid = 0; } @@ -1257,12 +1284,12 @@ void rv32f_fsgnjn_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) return; } -void rv32f_fsgnjx_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fsgnjx_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - uint32_t src1 = is_nan_boxed(freg_read_riscv(E, S, rs1)); - uint32_t src2 = is_nan_boxed(freg_read_riscv(E, S, rs2)); - - uint32_t result = (src1 & (-1 - (1 << 31))) | ((src1 ^ src2) & (1 << 31)); + uint32_t src1 = is_nan_boxed(freg_read_riscv(E, S, rs1)); + uint32_t src2 = is_nan_boxed(freg_read_riscv(E, S, rs2)); + uint32_t result = (src1 & (-1 - (1 << 31))) | ((src1 ^ src2) & (1 << 31)); freg_set_riscv(E, S, rd, nan_box(result)); @@ -1270,13 +1297,11 @@ void rv32f_fsgnjx_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } if (S->riscv->uncertain != NULL && S->riscv->uncertain->last_op.valid) { uncertain_check_part2_pc(E, S); - uncertain_inst_mv(S->riscv->uncertain, rd, rs1); S->riscv->uncertain->last_op.valid = 0; } @@ -1284,9 +1309,10 @@ void rv32f_fsgnjx_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) return; } -void rv32f_fmin_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fmin_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - rv32f_rep src1, src2, result; + rv32f_rep src1, src2, result; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); src2.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs2)); @@ -1318,9 +1344,10 @@ void rv32f_fmin_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) return; } -void rv32f_fmax_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fmax_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - rv32f_rep src1, src2, result; + rv32f_rep src1, src2, result; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); src2.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs2)); @@ -1352,13 +1379,13 @@ void rv32f_fmax_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) return; } -void rv32f_fcvt_w_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fcvt_w_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - rv32f_rep src1; - uint32_t result; - - uint8_t frm; - uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; + rv32f_rep src1; + uint32_t result; + uint8_t frm; + uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); @@ -1434,21 +1461,21 @@ void rv32f_fcvt_w_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void rv32f_fcvt_wu_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fcvt_wu_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - rv32f_rep src1; - uint32_t result; + rv32f_rep src1; + uint32_t result; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); - uint8_t frm; - uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; + uint8_t frm; + uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; /* *Rounding modes - Reference @@ -1522,13 +1549,13 @@ void rv32f_fcvt_wu_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void rv32f_fmv_x_w(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fmv_x_w(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { reg_set_riscv(E, S, rd, is_nan_boxed(freg_read_riscv(E, S, rs1))); @@ -1536,15 +1563,15 @@ void rv32f_fmv_x_w(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void rv32f_feq_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_feq_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - rv32f_rep src1, src2; + rv32f_rep src1, src2; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); src2.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs2)); @@ -1555,15 +1582,15 @@ void rv32f_feq_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void rv32f_flt_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_flt_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - rv32f_rep src1, src2; + rv32f_rep src1, src2; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); src2.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs2)); @@ -1574,13 +1601,13 @@ void rv32f_flt_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void rv32f_fle_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fle_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { rv32f_rep src1, src2; @@ -1593,22 +1620,23 @@ void rv32f_fle_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void rv32f_fclass_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fclass_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - //https://www.gnu.org/software/libc/manual/html_node/Floating-Point-Classes.html - //TODO - uint32_t shift; - rv32f_rep src1; + /* + * TODO: See https://www.gnu.org/software/libc/manual/html_node/Floating-Point-Classes.html + */ + uint32_t shift = 0; + rv32f_rep src1; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); - int class = fpclassify(src1.float_value); + int class = fpclassify(src1.float_value); switch (class) { @@ -1643,19 +1671,18 @@ void rv32f_fclass_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void rv32f_fcvt_s_w(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fcvt_s_w(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { //uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; //TODO check why there is a rm field? - rv32f_rep result; - - int32_t src1 = (int32_t)reg_read_riscv(E, S, rs1); + rv32f_rep result; + int32_t src1 = (int32_t)reg_read_riscv(E, S, rs1); result.float_value = (float)src1; //cast to float @@ -1665,19 +1692,18 @@ void rv32f_fcvt_s_w(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32f_fcvt_s_wu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fcvt_s_wu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { //uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; //TODO check why there is a rm field? - rv32f_rep result; //TODO test this - - uint32_t src1 = reg_read_riscv(E, S, rs1); + rv32f_rep result; //TODO test this + uint32_t src1 = reg_read_riscv(E, S, rs1); result.float_value = (float)src1; //cast to float @@ -1687,13 +1713,13 @@ void rv32f_fcvt_s_wu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32f_fmv_w_x(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32f_fmv_w_x(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { freg_set_riscv(E, S, rd, nan_box(reg_read_riscv(E, S, rs1))); @@ -1701,7 +1727,6 @@ void rv32f_fmv_w_x(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; @@ -1709,20 +1734,19 @@ void rv32f_fmv_w_x(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +/* + * RISC-V RV32D instructions + */ - -/* RISC-V RV32D instructions */ - -void rv32d_fld(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) +void +rv32d_fld(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) { - uint32_t addr = reg_read_riscv(E, S, rs1) + sign_extend(imm0, 12); - - uint64_t data_lsw = (uint64_t)superHreadlong(E, S, addr); - uint64_t data_msw = (uint64_t)superHreadlong(E, S, (addr+4)); - - uint64_t data = (data_msw << 32) | data_lsw; + uint32_t addr = reg_read_riscv(E, S, rs1) + sign_extend(imm0, 12); + uint64_t data_lsw = (uint64_t)superHreadlong(E, S, addr); + uint64_t data_msw = (uint64_t)superHreadlong(E, S, (addr+4)); + uint64_t data = (data_msw << 32) | data_lsw; freg_set_riscv(E, S, rd, data); @@ -1730,20 +1754,18 @@ void rv32d_fld(Engine *E, State *S, uint8_t rs1, uint8_t rd, uint16_t imm0) { taintprop(E, S, taintretreg(E,S,rs1), taintretmems(E,S,addr,8), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32d_fsd(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uint16_t imm5) +void +rv32d_fsd(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uint16_t imm5) { - uint32_t addr = reg_read_riscv(E, S, rs1) + sign_extend(imm0 + (imm5 << 5), 12); - - uint64_t data = freg_read_riscv(E, S, rs2); - - uint32_t data_lsw = (uint32_t)(data & 0xffffffff); - uint32_t data_msw = (uint32_t)((data >> 32) & 0xffffffff); + uint32_t addr = reg_read_riscv(E, S, rs1) + sign_extend(imm0 + (imm5 << 5), 12); + uint64_t data = freg_read_riscv(E, S, rs2); + uint32_t data_lsw = (uint32_t)(data & 0xffffffff); + uint32_t data_msw = (uint32_t)((data >> 32) & 0xffffffff); superHwritelong(E, S, addr, data_lsw); superHwritelong(E, S, addr+4, data_msw); @@ -1755,15 +1777,15 @@ void rv32d_fsd(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint16_t imm0, uin taintprop(E, S, taintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)(addr+i), kSunflowerTaintMemTypeMemory); } - } return; } -void rv32d_fmadd_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) +void +rv32d_fmadd_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) { - rv32d_rep src1, src2, src3, result; + rv32d_rep src1, src2, src3, result; src1.bit64_value = freg_read_riscv(E, S, rs1); src2.bit64_value = freg_read_riscv(E, S, rs2); @@ -1773,7 +1795,6 @@ void rv32d_fmadd_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, u switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, result.bit64_value); @@ -1782,13 +1803,13 @@ void rv32d_fmadd_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, u { taintprop(E, S, ftaintretreg(E,S,rs1), (ftaintretreg(E,S,rs2) | ftaintretreg(E,S,rs3)), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32d_fmsub_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) +void +rv32d_fmsub_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) { rv32d_rep src1, src2, src3, result; @@ -1800,7 +1821,6 @@ void rv32d_fmsub_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, u switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, result.bit64_value); @@ -1809,16 +1829,15 @@ void rv32d_fmsub_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, u { taintprop(E, S, ftaintretreg(E,S,rs1), (ftaintretreg(E,S,rs2) | ftaintretreg(E,S,rs3)), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - - } return; } -void rv32d_fnmsub_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) +void +rv32d_fnmsub_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) { - rv32d_rep src1, src2, src3, result; + rv32d_rep src1, src2, src3, result; src1.bit64_value = freg_read_riscv(E, S, rs1); src2.bit64_value = freg_read_riscv(E, S, rs2); @@ -1828,7 +1847,6 @@ void rv32d_fnmsub_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, result.bit64_value); @@ -1837,17 +1855,15 @@ void rv32d_fnmsub_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, { taintprop(E, S, ftaintretreg(E,S,rs1), (ftaintretreg(E,S,rs2) | ftaintretreg(E,S,rs3)), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - - - } return; } -void rv32d_fnmadd_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) +void +rv32d_fnmadd_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, uint8_t rm, uint8_t rd) { - rv32d_rep src1, src2, src3, result; + rv32d_rep src1, src2, src3, result; src1.bit64_value = freg_read_riscv(E, S, rs1); src2.bit64_value = freg_read_riscv(E, S, rs2); @@ -1857,7 +1873,6 @@ void rv32d_fnmadd_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, result.bit64_value); @@ -1866,18 +1881,17 @@ void rv32d_fnmadd_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rs3, { taintprop(E, S, ftaintretreg(E,S,rs1), (ftaintretreg(E,S,rs2) | ftaintretreg(E,S,rs3)), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - - } return; } -void rv32d_fadd_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fadd_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; - rv32d_rep src1, src2, result; + rv32d_rep src1, src2, result; src1.bit64_value = freg_read_riscv(E, S, rs1); src2.bit64_value = freg_read_riscv(E, S, rs2); @@ -1886,7 +1900,6 @@ void rv32d_fadd_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, result.bit64_value); @@ -1895,18 +1908,16 @@ void rv32d_fadd_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - - } return; } -void rv32d_fsub_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fsub_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; - - rv32d_rep src1, src2, result; + uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; + rv32d_rep src1, src2, result; src1.bit64_value = freg_read_riscv(E, S, rs1); src2.bit64_value = freg_read_riscv(E, S, rs2); @@ -1915,7 +1926,6 @@ void rv32d_fsub_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, result.bit64_value); @@ -1924,19 +1934,16 @@ void rv32d_fsub_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - - } return; } -void rv32d_fmul_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fmul_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - - uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; - - rv32d_rep src1, src2, result; + uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; + rv32d_rep src1, src2, result; src1.bit64_value = freg_read_riscv(E, S, rs1); src2.bit64_value = freg_read_riscv(E, S, rs2); @@ -1945,7 +1952,6 @@ void rv32d_fmul_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, result.bit64_value); @@ -1954,18 +1960,16 @@ void rv32d_fmul_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - - } return; } -void rv32d_fdiv_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fdiv_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; - - rv32d_rep src1, src2, result; + uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; + rv32d_rep src1, src2, result; src1.bit64_value = freg_read_riscv(E, S, rs1); src2.bit64_value = freg_read_riscv(E, S, rs2); @@ -1974,7 +1978,6 @@ void rv32d_fdiv_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, result.bit64_value); @@ -1983,27 +1986,24 @@ void rv32d_fdiv_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32d_fsqrt_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fsqrt_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { //rs2 is unused - uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; - - rv32d_rep src1, result; + uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; + rv32d_rep src1, result; src1.bit64_value = freg_read_riscv(E, S, rs1); - result.double_value = sqrt(src1.double_value); switch (rm) //TODO check rm value for rounding { - } freg_set_riscv(E, S, rd, result.bit64_value); @@ -2012,18 +2012,17 @@ void rv32d_fsqrt_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32d_fsgnj_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fsgnj_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - uint64_t src1 = freg_read_riscv(E, S, rs1); - uint64_t src2 = freg_read_riscv(E, S, rs2); - - uint64_t result = (src1 & ((uint64_t)(-1) - ((uint64_t)1 << 63))) | (src2 & ((uint64_t)1 << 63)); + uint64_t src1 = freg_read_riscv(E, S, rs1); + uint64_t src2 = freg_read_riscv(E, S, rs2); + uint64_t result = (src1 & ((uint64_t)(-1) - ((uint64_t)1 << 63))) | (src2 & ((uint64_t)1 << 63)); freg_set_riscv(E, S, rd, result); @@ -2031,18 +2030,17 @@ void rv32d_fsgnj_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32d_fsgnjn_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fsgnjn_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - uint64_t src1 = freg_read_riscv(E, S, rs1); - uint64_t src2 = freg_read_riscv(E, S, rs2); - - uint64_t result = (src1 & ((uint64_t)(-1) - ((uint64_t)1 << 63))) | (~src2 & ((uint64_t)1 << 63)); + uint64_t src1 = freg_read_riscv(E, S, rs1); + uint64_t src2 = freg_read_riscv(E, S, rs2); + uint64_t result = (src1 & ((uint64_t)(-1) - ((uint64_t)1 << 63))) | (~src2 & ((uint64_t)1 << 63)); freg_set_riscv(E, S, rd, result); @@ -2050,18 +2048,17 @@ void rv32d_fsgnjn_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32d_fsgnjx_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fsgnjx_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - uint64_t src1 = freg_read_riscv(E, S, rs1); - uint64_t src2 = freg_read_riscv(E, S, rs2); - - uint64_t result = (src1 & ((uint64_t)(-1) - ((uint64_t)1 << 63))) | ((src1 ^ src2) & ((uint64_t)1 << 63)); + uint64_t src1 = freg_read_riscv(E, S, rs1); + uint64_t src2 = freg_read_riscv(E, S, rs2); + uint64_t result = (src1 & ((uint64_t)(-1) - ((uint64_t)1 << 63))) | ((src1 ^ src2) & ((uint64_t)1 << 63)); freg_set_riscv(E, S, rd, result); @@ -2069,15 +2066,15 @@ void rv32d_fsgnjx_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32d_fmin_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fmin_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - rv32d_rep src1, src2, result; + rv32d_rep src1, src2, result; src1.bit64_value = freg_read_riscv(E, S, rs1); src2.bit64_value = freg_read_riscv(E, S, rs2); @@ -2090,19 +2087,18 @@ void rv32d_fmin_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32d_fmax_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fmax_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - rv32d_rep src1, src2, result; + rv32d_rep src1, src2, result; src1.bit64_value = freg_read_riscv(E, S, rs1); src2.bit64_value = freg_read_riscv(E, S, rs2); - result.double_value = fmax(src1.double_value, src2.double_value); freg_set_riscv(E, S, rd, result.bit64_value); @@ -2117,17 +2113,17 @@ void rv32d_fmax_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) return; } -void rv32d_fcvt_s_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fcvt_s_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { //uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; //TODO check why there is a rm field? //rs2 unused - rv32f_rep result; - rv32d_rep src1; + rv32f_rep result; + rv32d_rep src1; src1.bit64_value = freg_read_riscv(E, S, rs1); - result.float_value = (float)src1.double_value; //cast to float freg_set_riscv(E, S, rd, nan_box(result.bit_value)); @@ -2136,23 +2132,22 @@ void rv32d_fcvt_s_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32d_fcvt_d_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fcvt_d_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { //uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; //TODO check why there is a rm field? //rs2 unused - rv32d_rep result; - rv32f_rep src1; + rv32d_rep result; + rv32f_rep src1; src1.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); - result.double_value = (double)src1.float_value; //cast to double freg_set_riscv(E, S, rd, result.bit64_value); @@ -2161,15 +2156,15 @@ void rv32d_fcvt_d_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32d_feq_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_feq_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - rv32d_rep src1, src2; + rv32d_rep src1, src2; src1.bit64_value = freg_read_riscv(E, S, rs1); src2.bit64_value = freg_read_riscv(E, S, rs2); @@ -2180,15 +2175,15 @@ void rv32d_feq_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void rv32d_flt_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_flt_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - rv32d_rep src1, src2; + rv32d_rep src1, src2; src1.bit64_value = freg_read_riscv(E, S, rs1); src2.bit64_value = freg_read_riscv(E, S, rs2); @@ -2199,15 +2194,15 @@ void rv32d_flt_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void rv32d_fle_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fle_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - rv32d_rep src1, src2; + rv32d_rep src1, src2; src1.bit64_value = freg_read_riscv(E, S, rs1); src2.bit64_value = freg_read_riscv(E, S, rs2); @@ -2218,22 +2213,23 @@ void rv32d_fle_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), ftaintretreg(E,S,rs2), (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void rv32d_fclass_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fclass_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - //https://www.gnu.org/software/libc/manual/html_node/Floating-Point-Classes.html - //TODO - uint32_t shift; - rv32d_rep src1; + /* + * TODO: See https://www.gnu.org/software/libc/manual/html_node/Floating-Point-Classes.html + */ + uint32_t shift = 0; + rv32d_rep src1; src1.bit64_value = freg_read_riscv(E, S, rs1); - int class = fpclassify(src1.double_value); + int class = fpclassify(src1.double_value); switch (class) { @@ -2268,27 +2264,27 @@ void rv32d_fclass_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void rv32d_fcvt_w_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fcvt_w_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { //rs2 unused - rv32d_rep src1; + rv32d_rep src1; - uint8_t frm; - uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; + uint8_t frm; + uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; src1.bit64_value = freg_read_riscv(E, S, rs1); /* - *Rounding modes - Reference - *https://www.gnu.org/software/libc/manual/html_node/Rounding-Functions.html - */ + * Rounding modes - Reference + * https://www.gnu.org/software/libc/manual/html_node/Rounding-Functions.html + */ switch (rm) //TODO check rm value for rounding { case 0b000: //Round to nearest (ties to Even) @@ -2355,25 +2351,25 @@ void rv32d_fcvt_w_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void rv32d_fcvt_wu_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fcvt_wu_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - rv32d_rep src1; + rv32d_rep src1; src1.bit64_value = freg_read_riscv(E, S, rs1); - uint8_t frm; - uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; + uint8_t frm; + uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; /* - *Rounding modes - Reference - *https://www.gnu.org/software/libc/manual/html_node/Rounding-Functions.html - */ + * Rounding modes - Reference + * https://www.gnu.org/software/libc/manual/html_node/Rounding-Functions.html + */ switch (rm) //TODO check rm value for rounding { case 0b000: //Round to nearest (ties to Even) @@ -2440,21 +2436,19 @@ void rv32d_fcvt_wu_d(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, ftaintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypeRegister); - } return; } -void rv32d_fcvt_d_w(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fcvt_d_w(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { //uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; //TODO check why there is a rm field? - //rs2 unused - rv32d_rep result; - - int32_t src1 = (int32_t)reg_read_riscv(E, S, rs1); + rv32d_rep result; + int32_t src1 = (int32_t)reg_read_riscv(E, S, rs1); result.double_value = (double)src1; //cast to double @@ -2464,19 +2458,18 @@ void rv32d_fcvt_d_w(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -void rv32d_fcvt_d_wu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32d_fcvt_d_wu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { //uint8_t rm = ((instr_r *)&S->riscv->P.EX.instr)->funct3; //TODO check why there is a rm field? - rv32d_rep result; //TODO test this - - uint32_t src1 = reg_read_riscv(E, S, rs1); + rv32d_rep result; //TODO test this + uint32_t src1 = reg_read_riscv(E, S, rs1); result.double_value = (double)src1; //cast to double @@ -2486,23 +2479,29 @@ void rv32d_fcvt_d_wu(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { taintprop(E, S, taintretreg(E,S,rs1), 0, (uint64_t)rd, kSunflowerTaintMemTypefltRegister); - } return; } -/* RISC-V RV32UN instructions */ -void rv32un_unupg_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +/* + * RISC-V RV32UN instructions + */ + + + +void +rv32un_unupg_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { uncertain_inst_up1(S->riscv->uncertain, rd, rs1, rs2); } -void rv32un_ungcov_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) +void +rv32un_ungcov_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) { - rv32f_rep var; + rv32f_rep var; var.float_value = uncertain_inst_gcov(S->riscv->uncertain, rs1, rs2); @@ -2512,26 +2511,30 @@ void rv32un_ungcov_s(Engine *E, State *S, uint8_t rs1, uint8_t rs2, uint8_t rd) } -void rv32un_unsvar_s(Engine *E, State *S, uint8_t rs1, uint8_t _rs2, uint8_t rd) +void +rv32un_unsvar_s(Engine *E, State *S, uint8_t rs1, uint8_t _rs2, uint8_t rd) { - rv32f_rep var; + rv32f_rep var; var.bit_value = is_nan_boxed(freg_read_riscv(E, S, rs1)); uncertain_inst_sv(S->riscv->uncertain, rd, var.float_value); } -void rv32un_unclvar_s(Engine *E, State *S, uint8_t _rs1, uint8_t _rs2, uint8_t rd) +void +rv32un_unclvar_s(Engine *E, State *S, uint8_t _rs1, uint8_t _rs2, uint8_t rd) { uncertain_inst_sv(S->riscv->uncertain, rd, 0.0); } -void rv32un_uncpvar_s(Engine *E, State *S, uint8_t rs1, uint8_t _rs2, uint8_t rd) +void +rv32un_uncpvar_s(Engine *E, State *S, uint8_t rs1, uint8_t _rs2, uint8_t rd) { uncertain_inst_mv(S->riscv->uncertain, rd, rs1); } -void rv32un_un_part1(Engine *E, State *S, uint8_t _rs1, uint8_t _rd, uint16_t _imm0) +void +rv32un_un_part1(Engine *E, State *S, uint8_t _rs1, uint8_t _rd, uint16_t _imm0) { if (S->riscv->uncertain == NULL) { diff --git a/sim/pipeline-riscv.c b/sim/pipeline-riscv.c index e5b9fddc..a4a221d1 100644 --- a/sim/pipeline-riscv.c +++ b/sim/pipeline-riscv.c @@ -1,5 +1,6 @@ /* - Copyright (c) 2017-2018, Zhengyang Gu (author) + Copyright (c) 2017-2018, Zhengyang Gu (author) + 2019, Samuel Wong (author) All rights reserved. @@ -837,7 +838,7 @@ riscvstep(Engine *E, State *S, int drain_pipeline) S->superH->mem_access_type = MEM_ACCESS_NIL; } - /* Count # bits flipping in IF */ + /* Count # bits flipping in IF */ if (SF_BITFLIP_ANALYSIS) { S->Cycletrans += bit_flips_32(S->riscv->P.IF.instr, instrlong); diff --git a/sim/regaccess-riscv.c b/sim/regaccess-riscv.c index e6dd61c5..48c5ab22 100644 --- a/sim/regaccess-riscv.c +++ b/sim/regaccess-riscv.c @@ -34,59 +34,49 @@ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include -#include "sf.h" #include #include +#include "sf.h" -tuck -uint32_t reg_read_riscv(Engine *E, State *S, uint8_t n) +tuck uint32_t +reg_read_riscv(Engine *E, State *S, uint8_t n) { - uint32_t data; + /* + * BUG/TODO: Non-existing registers (e.g., CSRs) read as zero. See issue #31. + */ + uint32_t data = 0; if (n <= RISCV_GPR) { data = S->riscv->R[n]; } - - - switch(n) //For CSR access? - { - default: - { - } - } - return data; } -tuck -void reg_set_riscv(Engine *E, State *S, uint8_t n, uint32_t data) +tuck void +reg_set_riscv(Engine *E, State *S, uint8_t n, uint32_t data) { if (n <= RISCV_GPR && n != RISCV_X0) { S->riscv->R[n] = data; } - switch(n) //For CSR access? - { - case RISCV_X0: - { - } - default: - { - } - } - return; } -/* RV32F floating point register access */ -tuck -uint64_t freg_read_riscv(Engine *E, State *S, uint8_t n) +/* + * RV32F floating point register access + */ +tuck uint64_t +freg_read_riscv(Engine *E, State *S, uint8_t n) { - uint64_t data; + /* + * BUG/TODO: Non-existing registers (e.g., CSRs) read as zero. See issue #31. + */ + uint32_t data = 0; if (n < RF32FD_fMAX) { @@ -96,8 +86,8 @@ uint64_t freg_read_riscv(Engine *E, State *S, uint8_t n) return data; } -tuck -void freg_set_riscv(Engine *E, State *S, uint8_t n, uint64_t data) +tuck void +freg_set_riscv(Engine *E, State *S, uint8_t n, uint64_t data) { if (n < RF32FD_fMAX) { @@ -106,387 +96,3 @@ void freg_set_riscv(Engine *E, State *S, uint8_t n, uint64_t data) return; } - - - -void -Histogram_AddDist(Engine *E, State *S, Histogram *hist1, Histogram *hist2, Histogram *histDest){ - /* - * Add two distributions, considering overflow - */ - - uint16_t overflow_wid = 0; - uint32_t overflow_hi = 0; - - // Zero-out destination histogram - for (int k = 0; k < kNBINS; k++){ - histDest->bins[k] = 0; - } - - // Iterate, adding with overflow - for (int j = 0; j < kNBINS; j++){ - for (int i = 0; i < kNBINS; i++){ - overflow_wid = i+j; - - if (overflow_wid < kNBINS){ - overflow_hi = histDest->bins[i+j] + (uint32_t)((uint32_t)hist1->bins[i] * hist2->bins[j]); - - if (overflow_hi < 65536){ - histDest->bins[i+j] += hist1->bins[i] * hist2->bins[j]; - } - else{ - // Bin overflow error - mprint(E, S, nodeinfo, "WARN: encountered bin overflow in histogram operation\n"); - } - } - else{ - // Value overflow error - mprint(E, S, nodeinfo, "WARN: encountered value overflow in histogram operation\n"); - } - } - } - - return; -} - -void Histogram_ScalarMultiply(Engine *E, State *S, Histogram *hist, HistogramBinDatatype scalar){ - /* - * Multiply each bin with a scalar - */ - - for (int k = 0; k < kNBINS; k++){ - hist->bins[k] = scalar * hist->bins[k]; - } - - return; -} - -void Histogram_SubDist(Engine *E, State *S, Histogram *hist1, Histogram *hist2, Histogram *histDest){ - /* - * Subtract two distributions, considering overflow - */ - - // We want to reuse the code for AddDist. To do this, we transform in-place as follows - - // Negate one of the histograms (pick hist2) - Histogram_ScalarMultiply(E, S, hist2, -1); - - // Add together to give the result - Histogram_AddDist(E, S, hist1, hist2, histDest); - - // Undo the change to hist2 - Histogram_ScalarMultiply(E, S, hist2, -1); - - return; - - /* Caveat: Is the above equivalent to the following code in all cases? - * - UInt uncertain_SubDist(UInt Urs1, UInt Urs2, UInt Ud){ //Subtracts distributions - - uint32_t overflow_hi = 0; - - - int k = 0; - int j = 0; - int i = 0; - - // Empty Ud (just in case) - for(k = 0; k < 256; k++){ - Ud.weights[i] = 0; - } - - - for (j = 0; j < 256; j++){ - for(i=0; i<256; i++){ - if(i >= j){ - - overflow_hi = Ud.weights[i - j] + (uint32_t)((uint32_t)Urs1.weights[i] * Urs2.weights[j]); //Nasty casting here - - if(overflow_hi < 65536){ - Ud.weights[i - j] += Urs1.weights[i] * Urs2.weights[j]; - - }else{ - //Bin overflow error - } - }else{ - //Value underflow error - } - } - } - - return Ud; - } - */ - - -} - -void Histogram_CombDist(Engine *E, State *S, Histogram *hist1, Histogram *hist2, Histogram *histDest){ - /* - * Add two distograms in the simple fashion of adding corresponding bins together - */ - - for (int k = 0; k < kNBINS; k++){ - histDest->bins[k] = hist1->bins[k] * hist2->bins[k]; - } - - return; -} - -int Histogram_LowerBound(Engine *E, State *S, Histogram *hist){ - /* - * Returns the lower bound of the distribution, i.e. the bin index of the lowermost non-zero bin. - * - * Returns -1 if all bins are empty. - */ - - for (int k = 0; k < kNBINS; k++){ - if (hist->bins[k] != 0){ - return k; - } - } - - return -1; -} - -int Histogram_UpperBound(Engine *E, State *S, Histogram *hist){ - /* - * Returns the upper bound of the distribution, i.e. the bin index of the uppermost non-zero bin. - * - * Returns -1 if all bins are empty. - */ - - for (int k = kNBINS-1; k >= 0; k--){ - if (hist->bins[k] != 0){ - return k; - } - } - - return -1; -} - -void Histogram_DistLShift(Engine *E, State *S, Histogram *hist1, uint8_t Rs2, Histogram *histDest){ - /* - * DistLShift shifts the heights of the bins left by rs2, effectively subtracting rs2 from each bin. - * This reduces the mean of the distribution by rs2. - */ - int k = 0; - int i = 0; - - for(k = 0; k < 256; k++){ - histDest->bins[k] = 0; - } - - for(i = 0; i < 256; i++){ - if(i >= Rs2){ - histDest->bins[i-Rs2] = hist1->bins[i]; - } - } - - return; -} - -void Histogram_DistRShift(Engine *E, State *S, Histogram *hist1, uint8_t Rs2, Histogram *histDest){ - /* - * DistRShift shifts the heights of the bins right by rs2, effectively adding rs2 to each bin. - * This increases the mean of the distribution by rs2. - */ - int k = 0; - int i = 0; - uint16_t overflow_wid = 0; - - for(k = 0; k < 256; k++){ - histDest->bins[k] = 0; - } - - for(i = 0; i < 256; i++){ - overflow_wid = (int16_t) (i + Rs2); - if(overflow_wid < 256){ - histDest->bins[i+Rs2] = hist1->bins[i]; - } - } - - return; -} - - -uint8_t Histogram_ExpectedValue(Engine *E, State *S, Histogram *hist){ - /* - * Exp returns the expected value of the histogram. This provides an estimate of the - * variable and allows the histogram to be converted into a point value. - */ - int sum = 0; - int n = 0; - int mean = 0; - int i = 0; - uint8_t Rd = 0; - - for(i = 0; i<256; i++){ - sum += ((int)hist->bins[i] * i); - n += (int)hist->bins[i]; - } - - mean = sum / n; - Rd = (uint8_t) mean; - - return Rd; -} - - -uint32_t -Histogram_DistLess(Engine *E, State *S, Histogram *hist, uint32_t Rs2){ - /* - * DistLess returns the probability Pr(X < Rs2). - * X is a discrete random variable distributed according to the relative frequencies of hist1. - * The probability is returned as an unsigned integer between 0 and 100 representing a percentage. - * It is expected that this instruction will often be followed by one of the branch instructions - * in the base instruction set. - */ - int i = 0; - int num = 0; - int denom = 0; - uint32_t outcome = 0; - uint32_t Rd = 0; - - - for(i = 0; i < 256; i++){ - if(i < Rs2){ - num = num + hist->bins[i]; //If it is less then - } - denom = denom + hist->bins[i]; - } - - if(denom!=0){ - outcome = (num * 100) / denom; //Note this is integer division. Note that the times by 100 is to make it a percent rather than decimal which cannot be stored easily - Rd = outcome; - return Rd; - }else{ - Rd = -1; - return Rd; - } -} - -uint32_t Histogram_DistGrt(Engine *E, State *S, Histogram *hist, uint32_t Rs2){ - /* - * DistLess returns the probability Pr(X >= Rs2). - * X is a discrete random variable distributed according to the relative frequencies of hist1. - * The probability is returned as an unsigned integer between 0 and 100 representing a percentage. - * It is expected that this instruction will often be followed by one of the branch instructions - * in the base instruction set. - */ - int i = 0; - int num = 0; - int denom = 0; - uint32_t outcome = 0; - uint32_t Rd = 0; - - for(i = 0; i < 256; i++){ - if(i >= Rs2){ - num = num + hist->bins[i]; //If it is less then - } - denom = denom + hist->bins[i]; - } - - if(denom!=0){ - outcome = (num * 100) / denom; //Note this is integer division. Note that the times by 100 is to make it a percent rather than decimal which cannot be stored easily - Rd = outcome; - return Rd; - }else{ - Rd = -1; - return Rd; - } -} - -void Histogram_LDDist(Engine *E, State *S, Histogram *histogram, HistogramBinDatatype *bins){ - /* - * Load a kNBINS-sized array of HistogramBinDatatype into the Histogram class - */ - memcpy(histogram->bins, bins, sizeof(HistogramBinDatatype)*kNBINS); - - return; -} - -void Histogram_LDRandom(Engine *E, State *S, Histogram *histogram){ - /* - * Initialise *histogram with random values in each bin - */ - - // Create array - HistogramBinDatatype array[kNBINS] = {}; - for (int i = 0; i < kNBINS; i++){ - array[i] = (rand()/(double)RAND_MAX) * 255; - /* - * Picked some reasonable max value allowing by-eye debugging, increase to data type maximum later: - * array[i] = (rand()/(double)RAND_MAX) * ((HistogramBinDatatype)~(HistogramBinDatatype)0); - * The final expression finds the maximum value this datatype can take - */ - } - - // Load into histogram - Histogram_LDDist(E, S, histogram, array); - - return; -} - -double Histogram_MeanFrequency(Engine *E, State *S, Histogram *histogram){ - /* - * Return the mean frequency of a histogram, i.e. the average bin value (not weighted by index) - */ - - double sum = 0; - - for (int i = 0; i < kNBINS; i++){ - sum += histogram->bins[i]; - } - - return sum / (double)kNBINS; -} - - -void Histogram_PrettyPrint(Engine *E, State *S, Histogram *histogram){ - /* - * Pretty-print ("ASCII-graph") a normalised histogram representation, like so: - * - * +-----> bin value - * | - * | # - * | ## - * | ### - * | ## - * | # - * | - * V bin index - * - */ - - double normalised[kNBINS] = {}; - double meanFreq = Histogram_MeanFrequency(E, S, histogram); - - /*HistogramBinDatatype FULLSCALE = (HistogramBinDatatype)~(HistogramBinDatatype)0;*/ - // This expression finds the maximum value this datatype can take - - // Alternatively, auto-scaling could be done by the following: - double FULLSCALE = 3 * meanFreq; - - const int FULLSCALE_NUMBER_OF_CHARS = 40; - - for (int i = 0; i < kNBINS; i++){ - normalised[i] = histogram->bins[i] / FULLSCALE; - } - - mprint(E, S, nodeinfo, "Histogram mean frequency (mean bin occupation): %.3f\n", meanFreq); - mprint(E, S, nodeinfo, "bin | value | graphical representation (scaled rel. to mean freq)\n"); - mprint(E, S, nodeinfo, "----+-------+----------------------------------------------------\n"); - - for (int i = 0; i < kNBINS; i++){ - mprint(E, S, nodeinfo, "%03u | %-5u | ", i, histogram->bins[i]); - /*mprint(E, S, nodeinfo, "%f\n", (normalised[i]));*/ - /*mprint(E, S, nodeinfo, "%f\n", (normalised[i]*FULLSCALE_NUMBER_OF_CHARS));*/ - for (int j = 0; j < (int)(normalised[i]*FULLSCALE_NUMBER_OF_CHARS); j++){ - mprint(E, S, nodeinfo, "#"); - } - mprint(E, S, nodeinfo, "\n"); - } - - return; -} diff --git a/sim/regs-riscv.h b/sim/regs-riscv.h index 83578e9c..6212f51c 100644 --- a/sim/regs-riscv.h +++ b/sim/regs-riscv.h @@ -1,6 +1,6 @@ /* Copyright (c) 2017-2018, Zhengyang Gu (author) - + All rights reserved. Redistribution and use in source and binary forms, with or without @@ -35,8 +35,6 @@ POSSIBILITY OF SUCH DAMAGE. */ -#include "inst_uncertain.h" - enum { RISCV_X0 = 0, @@ -136,190 +134,130 @@ enum RISCV_X31 = 31, RISCV_T6 = 31, - /*Number of general purpose registers (x0 is not considered as general purpose)*/ - RISCV_GPR = 31, + /* + * Number of general purpose registers (x0 is not considered as general purpose) + */ + RISCV_GPR = 31, - RISCV_XMAX, + RISCV_XMAX, }; -/* RISC-V floating point registers */ +/* + * RISC-V floating point registers + */ enum { - RV32FD_f0 = 0, - RV32FD_ft0 = 0, + RV32FD_f0 = 0, + RV32FD_ft0 = 0, - RV32FD_f1 = 1, - RV32FD_ft1 = 1, + RV32FD_f1 = 1, + RV32FD_ft1 = 1, - RV32FD_f2 = 2, - RV32FD_ft2 = 2, + RV32FD_f2 = 2, + RV32FD_ft2 = 2, - RV32FD_f3 = 3, - RV32FD_ft3 = 3, + RV32FD_f3 = 3, + RV32FD_ft3 = 3, - RV32FD_f4 = 4, - RV32FD_ft4 = 4, + RV32FD_f4 = 4, + RV32FD_ft4 = 4, - RV32FD_f5 = 5, - RV32FD_ft5 = 5, + RV32FD_f5 = 5, + RV32FD_ft5 = 5, - RV32FD_f6 = 6, - RV32FD_ft6 = 6, + RV32FD_f6 = 6, + RV32FD_ft6 = 6, - RV32FD_f7 = 7, - RV32FD_ft7 = 7, + RV32FD_f7 = 7, + RV32FD_ft7 = 7, - RV32FD_f8 = 8, - RV32FD_fs0 = 8, + RV32FD_f8 = 8, + RV32FD_fs0 = 8, - RV32FD_f9 = 9, - RV32FD_fs1 = 9, + RV32FD_f9 = 9, + RV32FD_fs1 = 9, - RV32FD_f10 = 10, - RV32FD_fa0 = 10, + RV32FD_f10 = 10, + RV32FD_fa0 = 10, - RV32FD_f11 = 11, - RV32FD_fa1 = 11, + RV32FD_f11 = 11, + RV32FD_fa1 = 11, - RV32FD_f12 = 12, - RV32FD_fa2 = 12, + RV32FD_f12 = 12, + RV32FD_fa2 = 12, - RV32FD_f13 = 13, - RV32FD_fa3 = 13, + RV32FD_f13 = 13, + RV32FD_fa3 = 13, - RV32FD_f14 = 14, - RV32FD_fa4 = 14, + RV32FD_f14 = 14, + RV32FD_fa4 = 14, - RV32FD_f15 = 15, - RV32FD_fa5 = 15, + RV32FD_f15 = 15, + RV32FD_fa5 = 15, - RV32FD_f16 = 16, - RV32FD_fa6 = 16, + RV32FD_f16 = 16, + RV32FD_fa6 = 16, - RV32FD_f17 = 17, - RV32FD_fa7 = 17, + RV32FD_f17 = 17, + RV32FD_fa7 = 17, - RV32FD_f18 = 18, - RV32FD_fs2 = 18, + RV32FD_f18 = 18, + RV32FD_fs2 = 18, - RV32FD_f19 = 19, - RV32FD_fs3 = 19, + RV32FD_f19 = 19, + RV32FD_fs3 = 19, - RV32FD_f20 = 20, - RV32FD_fs4 = 20, + RV32FD_f20 = 20, + RV32FD_fs4 = 20, - RV32FD_f21 = 21, - RV32FD_fs5 = 21, + RV32FD_f21 = 21, + RV32FD_fs5 = 21, - RV32FD_f22 = 22, - RV32FD_fs6 = 22, + RV32FD_f22 = 22, + RV32FD_fs6 = 22, - RV32FD_f23 = 23, - RV32FD_fs7 = 23, + RV32FD_f23 = 23, + RV32FD_fs7 = 23, - RV32FD_f24 = 24, - RV32FD_fs8 = 24, + RV32FD_f24 = 24, + RV32FD_fs8 = 24, - RV32FD_f25 = 25, - RV32FD_fs9 = 25, + RV32FD_f25 = 25, + RV32FD_fs9 = 25, - RV32FD_f26 = 26, - RV32FD_fs10 = 26, + RV32FD_f26 = 26, + RV32FD_fs10 = 26, - RV32FD_f27 = 27, - RV32FD_fs11 = 27, + RV32FD_f27 = 27, + RV32FD_fs11 = 27, - RV32FD_f28 = 28, - RV32FD_ft8 = 28, + RV32FD_f28 = 28, + RV32FD_ft8 = 28, - RV32FD_f29 = 29, - RV32FD_ft9 = 29, + RV32FD_f29 = 29, + RV32FD_ft9 = 29, - RV32FD_f30 = 30, - RV32FD_ft10 = 30, + RV32FD_f30 = 30, + RV32FD_ft10 = 30, - RV32FD_f31 = 31, - RV32FD_ft11 = 31, + RV32FD_f31 = 31, + RV32FD_ft11 = 31, - /*Number of floating point registers*/ - RF32FD_fMAX = 32 + /* + * Number of floating point registers + */ + RF32FD_fMAX = 32 }; typedef union { - uint32_t bit_value; - float float_value; + uint32_t bit_value; + float float_value; } rv32f_rep; typedef union { - uint64_t bit64_value; - double double_value; + uint64_t bit64_value; + double double_value; } rv32d_rep; - - - - -/* - * Histograms (Idea: Alexa's final project thesis, Initial implementation: Jan (jh2109)) - */ - - -#define kNBINS 8 -typedef uint16_t HistogramBinDatatype; - -typedef struct -{ - HistogramBinDatatype bins[kNBINS]; -} Histogram; - -// Add two distributions, considering overflow -void Histogram_AddDist(Engine *E, State *S, Histogram *hist1, Histogram *hist2, Histogram *histDest); - -// Multiply each bin with a scalar -void Histogram_ScalarMultiply(Engine *E, State *S, Histogram *hist, HistogramBinDatatype scalar); - -// Subtract two distributions, considering overflow -void Histogram_SubDist(Engine *E, State *S, Histogram *hist1, Histogram *hist2, Histogram *histDest); - -// Add two distograms in the simple fashion of adding corresponding bins together -void Histogram_CombDist(Engine *E, State *S, Histogram *hist1, Histogram *hist2, Histogram *histDest); - -// Returns the lower bound of the distribution, i.e. the bin index of the lowermost non-zero bin. -// Returns -1 if all bins are empty. -int Histogram_LowerBound(Engine *E, State *S, Histogram *hist); - -// Returns the upper bound of the distribution, i.e. the bin index of the uppermost non-zero bin. -// Returns -1 if all bins are empty. -int Histogram_UpperBound(Engine *E, State *S, Histogram *hist); - -// Subtracts Rs2 from all (Engine *E, State *S, shifting left) -void Histogram_DistLShift(Engine *E, State *S, Histogram *hist1, uint8_t Rs2, Histogram *histDest); - -// Adds Rs2 from all (Engine *E, State *S, shifting right) -void Histogram_DistRShift(Engine *E, State *S, Histogram *hist1, uint8_t Rs2, Histogram *histDest); - -//Works out the mean -uint8_t Histogram_ExpectedValue(Engine *E, State *S, Histogram *hist); - -// DistLess returns the probability Pr(Engine *E, State *S, X < Rs2) -uint32_t Histogram_DistLess(Engine *E, State *S, Histogram *hist, uint32_t Rs2); - -// DistGrt returns the probability Pr(Engine *E, State *S, X >= Rs2) -uint32_t Histogram_DistGrt(Engine *E, State *S, Histogram *hist, uint32_t Rs2); - -// Load distribution -void Histogram_LDDist(Engine *E, State *S, Histogram *histogram, HistogramBinDatatype bins[kNBINS]); - -// Load random histogram -void Histogram_LDRandom(Engine *E, State *S, Histogram *histogram); - -// Return mean of given histogram -double Histogram_Mean(Engine *E, State *S, Histogram *histogram); - -// Pretty-print histogram distribution -void Histogram_PrettyPrint(Engine *E, State *S, Histogram *histogram); - -// Return the mean frequency of a histogram, i.e. the average bin value (Engine *E, State *S, not weighted by index) -double Histogram_MeanFrequency(Engine *E, State *S, Histogram *histogram); diff --git a/sim/sf-riscv.y b/sim/sf-riscv.y index 9dbe74e2..6539aec3 100755 --- a/sim/sf-riscv.y +++ b/sim/sf-riscv.y @@ -4520,6 +4520,6 @@ yyerror(char *err) { merror(yyengine, "Invalid command! (for riscv)"); clearistream(yyengine); - + return 0; } diff --git a/sim/sf.h b/sim/sf.h index dcf8a80e..b458b4f8 100755 --- a/sim/sf.h +++ b/sim/sf.h @@ -86,11 +86,11 @@ #include "interrupts-ti-msp430.h" #include "taint.h" #include "inst_uncertain.h" +#include "uncertain-histogram.h" #include "machine-hitachi-sh.h" #include "machine-riscv.h" #include "dev430x1xx.h" #include "machine-ti-msp430.h" #include "main.h" -#include "inst_uncertain.h" #include "mfns.h" #include "randgen.h" \ No newline at end of file diff --git a/sim/tokenhandling.c b/sim/tokenhandling.c index e5ad6a8b..ed912dc8 100755 --- a/sim/tokenhandling.c +++ b/sim/tokenhandling.c @@ -42,13 +42,13 @@ void munchinput(Engine *E, char *buf) { - int eaten = 0; + int eaten = 0; if (strlen(buf) > 0) { - while (eaten < strlen(buf)) - { + while (eaten < strlen(buf)) + { char *tptr; Datum *t1; @@ -75,7 +75,7 @@ munchinput(Engine *E, char *buf) } tptr = t1->data; - /* Throw away all chars till we see a non-sepchar */ + /* Throw away all chars till we see a non-sepchar */ while (isasmsep(buf[eaten]) && (eaten < strlen(buf))) { eaten++; @@ -84,8 +84,8 @@ munchinput(Engine *E, char *buf) /* */ /* I refer to tokens such as '(' etc. as "sticky": */ /* they may be "stuck" onto another token, and are */ - /* NOT separators : we have to allocate a list entry */ - /* for them. So, get one sticky char: */ + /* NOT separators : we have to allocate a list entry */ + /* for them. So, get one sticky char: */ /* */ if (issticky(buf[eaten])) { @@ -138,7 +138,7 @@ munchinput(Engine *E, char *buf) E->istream.tail = E->istream.head = E->istream.masthead = t1; /* */ - /* NOTE tail and head now point to the lone datum */ + /* NOTE tail and head now point to the lone datum */ /* and they _both_ have null pre- and next-. */ /* */ E->istream.masthead->prev = NULL; @@ -153,7 +153,7 @@ munchinput(Engine *E, char *buf) else { /* */ - /* Add new datum to _tail_ of list. MUST keep it FIFO */ + /* Add new datum to _tail_ of list. MUST keep it FIFO */ /* for the asm to be parsed correctly. */ /* */ t1->next = E->istream.tail; @@ -207,7 +207,7 @@ scan_labels_and_globalvars(Engine *E) while (tmpistream != NULL) { - /* If it is new a label, add it to labellist */ + /* If it is new a label, add it to labellist */ if (tmpistream->data[strlen(tmpistream->data)-1] == ':') { Datum* tmplabel = (Datum *) mmalloc(E, sizeof(Datum), @@ -252,7 +252,7 @@ scan_labels_and_globalvars(Engine *E) { //mprint(E, NULL, siminfo, "Adding new item to label list"); /* */ - /* Add new datum to _tail_ of list. */ + /* Add new datum to _tail_ of list. */ /* */ tmplabel->next = E->labellist.tail; E->labellist.tail->prev = tmplabel; @@ -319,7 +319,7 @@ scan_labels_and_globalvars(Engine *E) { //mprint(E, NULL, siminfo, "Adding new item to label list"); /* */ - /* Add new datum to _tail_ of list. */ + /* Add new datum to _tail_ of list. */ /* */ tmplabel->next = E->labellist.tail; E->labellist.tail->prev = tmplabel; diff --git a/sim/uncertain-histogram.c b/sim/uncertain-histogram.c new file mode 100644 index 00000000..1ef6d94a --- /dev/null +++ b/sim/uncertain-histogram.c @@ -0,0 +1,516 @@ +/* + Copyright (c) 2019, Jan Heck (author), based on work from + M.Eng. project of Alexa Belsham. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include "sf.h" + + +/* + * Add two distributions, considering overflow. + */ +void +Histogram_AddDist(Engine *E, State *S, Histogram *hist1, Histogram *hist2, Histogram *histDest) +{ + uint16_t overflow_wid = 0; + uint32_t overflow_hi = 0; + + /* + * Zero-out destination histogram + */ + for (int k = 0; k < kUncertainAluHistogramBins; k++) + { + histDest->bins[k] = 0; + } + + /* + * Iterate, adding with overflow + */ + for (int j = 0; j < kUncertainAluHistogramBins; j++)\ + { + for (int i = 0; i < kUncertainAluHistogramBins; i++) + { + overflow_wid = i+j; + + if (overflow_wid < kUncertainAluHistogramBins) + { + overflow_hi = histDest->bins[i+j] + (uint32_t)((uint32_t)hist1->bins[i] * hist2->bins[j]); + + if (overflow_hi < 65536) + { + histDest->bins[i+j] += hist1->bins[i] * hist2->bins[j]; + } + else + { + /* + * Bin overflow error + */ + mprint(E, S, nodeinfo, "WARN: encountered bin overflow in histogram operation\n"); + } + } + else + { + /* + * Value overflow error + */ + mprint(E, S, nodeinfo, "WARN: encountered value overflow in histogram operation\n"); + } + } + } + + return; +} + + +/* + * Multiply each bin with a scalar + */ +void +Histogram_ScalarMultiply(Engine *E, State *S, Histogram *hist, HistogramBinDatatype scalar) +{ + for (int k = 0; k < kUncertainAluHistogramBins; k++) + { + hist->bins[k] = scalar * hist->bins[k]; + } + + return; +} + + +/* + * Subtract two distributions, considering overflow + */ +void +Histogram_SubDist(Engine *E, State *S, Histogram *hist1, Histogram *hist2, Histogram *histDest) +{ + /* + * We want to reuse the code for AddDist. To do this, we transform in-place as follows: + */ + + + /* + * Negate one of the histograms (pick hist2) + */ + Histogram_ScalarMultiply(E, S, hist2, -1); + + /* + * Add together to give the result + */ + Histogram_AddDist(E, S, hist1, hist2, histDest); + + /* + * Undo the change to hist2 + */ + Histogram_ScalarMultiply(E, S, hist2, -1); + + + /* + * Caveat: Is the above equivalent to the following code in all cases? + * + UInt uncertain_SubDist(UInt Urs1, UInt Urs2, UInt Ud){ //Subtracts distributions + + uint32_t overflow_hi = 0; + + + int k = 0; + int j = 0; + int i = 0; + + // Empty Ud (just in case) + for(k = 0; k < 256; k++){ + Ud.weights[i] = 0; + } + + + for (j = 0; j < 256; j++){ + for(i=0; i<256; i++){ + if(i >= j){ + + overflow_hi = Ud.weights[i - j] + (uint32_t)((uint32_t)Urs1.weights[i] * Urs2.weights[j]); //Nasty casting here + + if(overflow_hi < 65536){ + Ud.weights[i - j] += Urs1.weights[i] * Urs2.weights[j]; + + }else{ + //Bin overflow error + } + }else{ + //Value underflow error + } + } + } + + return Ud; + } + */ + + return; +} + + +/* + * Add two distograms in the simple fashion of adding corresponding bins together + */ +void +Histogram_CombDist(Engine *E, State *S, Histogram *hist1, Histogram *hist2, Histogram *histDest) +{ + for (int k = 0; k < kUncertainAluHistogramBins; k++) + { + histDest->bins[k] = hist1->bins[k] * hist2->bins[k]; + } + + return; +} + + +/* + * Returns the lower bound of the distribution, i.e. the bin index of the lowermost non-zero bin. + * + * Returns -1 if all bins are empty. + */ +int +Histogram_LowerBound(Engine *E, State *S, Histogram *hist) +{ + for (int k = 0; k < kUncertainAluHistogramBins; k++) + { + if (hist->bins[k] != 0) + { + return k; + } + } + + return -1; +} + + +/* + * Returns the upper bound of the distribution, i.e. the bin index of the uppermost non-zero bin. + * + * Returns -1 if all bins are empty. + */ +int +Histogram_UpperBound(Engine *E, State *S, Histogram *hist) +{ + for (int k = kUncertainAluHistogramBins-1; k >= 0; k--) + { + if (hist->bins[k] != 0) + { + return k; + } + } + + return -1; +} + + +/* + * DistLShift shifts the heights of the bins left by rs2, effectively subtracting rs2 from each bin. + * This reduces the mean of the distribution by rs2. + */ +void +Histogram_DistLShift(Engine *E, State *S, Histogram *hist1, uint8_t Rs2, Histogram *histDest) +{ + int k = 0; + int i = 0; + + for(k = 0; k < 256; k++) + { + histDest->bins[k] = 0; + } + + for(i = 0; i < 256; i++) + { + if(i >= Rs2) + { + histDest->bins[i-Rs2] = hist1->bins[i]; + } + } + + return; +} + + +/* + * DistRShift shifts the heights of the bins right by rs2, effectively adding rs2 to each bin. + * This increases the mean of the distribution by rs2. + */ +void +Histogram_DistRShift(Engine *E, State *S, Histogram *hist1, uint8_t Rs2, Histogram *histDest) +{ + int k = 0; + int i = 0; + uint16_t overflow_wid = 0; + + for(k = 0; k < 256; k++) + { + histDest->bins[k] = 0; + } + + for(i = 0; i < 256; i++) + { + overflow_wid = (int16_t) (i + Rs2); + if(overflow_wid < 256) + { + histDest->bins[i+Rs2] = hist1->bins[i]; + } + } + + return; +} + + +/* + * Exp returns the expected value of the histogram. This provides an estimate of the + * variable and allows the histogram to be converted into a point value. + */ +uint8_t +Histogram_ExpectedValue(Engine *E, State *S, Histogram *hist) +{ + int sum = 0; + int n = 0; + int mean = 0; + int i = 0; + uint8_t Rd = 0; + + for(i = 0; i<256; i++) + { + sum += ((int)hist->bins[i] * i); + n += (int)hist->bins[i]; + } + + mean = sum / n; + Rd = (uint8_t) mean; + + return Rd; +} + + +/* + * DistLess returns the probability Pr(X < Rs2). + * X is a discrete random variable distributed according to the relative frequencies of hist1. + * The probability is returned as an unsigned integer between 0 and 100 representing a percentage. + * It is expected that this instruction will often be followed by one of the branch instructions + * in the base instruction set. + */ +uint32_t +Histogram_DistLess(Engine *E, State *S, Histogram *hist, uint32_t Rs2) +{ + int i = 0; + int num = 0; + int denom = 0; + uint32_t outcome = 0; + uint32_t Rd = 0; + + for(i = 0; i < 256; i++) + { + if(i < Rs2) + { + num = num + hist->bins[i]; //If it is less then + } + denom = denom + hist->bins[i]; + } + + if(denom!=0) + { + outcome = (num * 100) / denom; //Note this is integer division. Note that the times by 100 is to make it a percent rather than decimal which cannot be stored easily + Rd = outcome; + return Rd; + } + else + { + Rd = -1; + return Rd; + } +} + + +/* + * DistLess returns the probability Pr(X >= Rs2). + * X is a discrete random variable distributed according to the relative frequencies of hist1. + * The probability is returned as an unsigned integer between 0 and 100 representing a percentage. + * It is expected that this instruction will often be followed by one of the branch instructions + * in the base instruction set. + */ +uint32_t +Histogram_DistGrt(Engine *E, State *S, Histogram *hist, uint32_t Rs2) +{ + int i = 0; + int num = 0; + int denom = 0; + uint32_t outcome = 0; + uint32_t Rd = 0; + + for(i = 0; i < 256; i++) + { + if(i >= Rs2) + { + num = num + hist->bins[i]; //If it is less then + } + denom = denom + hist->bins[i]; + } + + if(denom!=0) + { + /* + * Note this is integer division. Note that the times by 100 is + * to make it a percent rather than decimal which cannot be stored + * easily. + */ + outcome = (num * 100) / denom; + Rd = outcome; + + return Rd; + } + else + { + Rd = -1; + + return Rd; + } +} + + +/* + * Load a kUncertainAluHistogramBins-sized array of HistogramBinDatatype into the Histogram class + */ +void +Histogram_LDDist(Engine *E, State *S, Histogram *histogram, HistogramBinDatatype *bins) +{ + memcpy(histogram->bins, bins, sizeof(HistogramBinDatatype)*kUncertainAluHistogramBins); + + return; +} + + +/* + * Initialise *histogram with random values in each bin + */ +void +Histogram_LDRandom(Engine *E, State *S, Histogram *histogram) +{ + /* + * Create array + */ + HistogramBinDatatype array[kUncertainAluHistogramBins] = {}; + for (int i = 0; i < kUncertainAluHistogramBins; i++) + { + array[i] = (rand()/(double)RAND_MAX) * 255; + /* + * Picked some reasonable max value allowing by-eye debugging, increase to data type maximum later: + * array[i] = (rand()/(double)RAND_MAX) * ((HistogramBinDatatype)~(HistogramBinDatatype)0); + * The final expression finds the maximum value this datatype can take + */ + } + + /* + * Load into histogram + */ + Histogram_LDDist(E, S, histogram, array); + + return; +} + + +/* + * Return the mean frequency of a histogram, i.e. the average bin value (not weighted by index) + */ +double +Histogram_MeanFrequency(Engine *E, State *S, Histogram *histogram) +{ + double sum = 0; + + for (int i = 0; i < kUncertainAluHistogramBins; i++){ + sum += histogram->bins[i]; + } + + return sum / (double)kUncertainAluHistogramBins; +} + + +/* + * Pretty-print ("ASCII-graph") a normalised histogram representation, like so: + * + * +-----> bin value + * | + * | # + * | ## + * | ### + * | ## + * | # + * | + * V bin index + * + */ +void +Histogram_PrettyPrint(Engine *E, State *S, Histogram *histogram) +{ + double normalised[kUncertainAluHistogramBins] = {}; + double meanFreq = Histogram_MeanFrequency(E, S, histogram); + + /*HistogramBinDatatype FULLSCALE = (HistogramBinDatatype)~(HistogramBinDatatype)0;*/ + // This expression finds the maximum value this datatype can take + + /* + * Alternatively, auto-scaling could be done by the following: + */ + double FULLSCALE = 3 * meanFreq; + + const int FULLSCALE_NUMBER_OF_CHARS = 40; + + for (int i = 0; i < kUncertainAluHistogramBins; i++) + { + normalised[i] = histogram->bins[i] / FULLSCALE; + } + + mprint(E, S, nodeinfo, "Histogram mean frequency (mean bin occupation): %.3f\n", meanFreq); + mprint(E, S, nodeinfo, "bin | value | graphical representation (scaled rel. to mean freq)\n"); + mprint(E, S, nodeinfo, "----+-------+----------------------------------------------------\n"); + + for (int i = 0; i < kUncertainAluHistogramBins; i++) + { + mprint(E, S, nodeinfo, "%03u | %-5u | ", i, histogram->bins[i]); + /*mprint(E, S, nodeinfo, "%f\n", (normalised[i]));*/ + /*mprint(E, S, nodeinfo, "%f\n", (normalised[i]*FULLSCALE_NUMBER_OF_CHARS));*/ + for (int j = 0; j < (int)(normalised[i]*FULLSCALE_NUMBER_OF_CHARS); j++){ + mprint(E, S, nodeinfo, "#"); + } + mprint(E, S, nodeinfo, "\n"); + } + + return; +} diff --git a/sim/uncertain-histogram.h b/sim/uncertain-histogram.h new file mode 100644 index 00000000..146ea586 --- /dev/null +++ b/sim/uncertain-histogram.h @@ -0,0 +1,51 @@ +/* + Copyright (c) 2019, Jan Heck (author), based on work from + M.Eng. project of Alexa Belsham. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +typedef uint16_t HistogramBinDatatype; + +enum +{ + + kUncertainAluHistogramBins = 8, +}; + +typedef struct +{ + HistogramBinDatatype bins[kUncertainAluHistogramBins]; +} Histogram;