Working test groups: binop, floating_point, alloc

parent edd644e3
......@@ -27,6 +27,7 @@ default = ["aot"]
aot = []
jit = []
sel4-rumprun = []
sel4-rumprun-target-side = []
[build-dependencies]
gcc = "0.3"
......@@ -34,8 +35,7 @@ gcc = "0.3"
[dependencies]
ast = {path = "src/ast"}
utils = {path = "src/utils"}
gc = {path = "src/gc"}
#gc = {path = "src/gc"}
field-offset = "0.1.1"
libloading = "0.3"
......@@ -52,3 +52,12 @@ docopt = "0.6"
petgraph = "0.4.1"
extprim = "*"
num-traits = "*"
[target.x86_64-unknown-linux-gnu.dependencies]
gc = { path = "src/gc", default-features = false}
[target.x86_64-apple-darwin.dependencies]
gc = { path = "src/gc", default-features = false}
[target.x86_64-rumprun-netbsd.dependencies]
gc = { path = "src/gc", default-features = false, features = ["sel4-rumprun-target-side"], target = "x86_64-rumprun-netbsd"}
......@@ -13,7 +13,9 @@
// limitations under the License.
extern crate gcc;
use std::env;
#[cfg(not(feature = "sel4-rumprun-target-side"))]
#[cfg(any(target_os = "macos", target_os = "linux"))]
#[cfg(target_arch = "x86_64")]
fn main() {
......@@ -24,6 +26,7 @@ fn main() {
.compile("libswap_stack.a");
}
#[cfg(not(feature = "sel4-rumprun-target-side"))]
#[cfg(target_os = "linux")]
#[cfg(target_arch = "aarch64")]
fn main() {
......@@ -35,6 +38,7 @@ fn main() {
}
// This is here to enable cross compiling from windows/x86_64 to linux/aarch64
#[cfg(not(feature = "sel4-rumprun-target-side"))]
#[cfg(target_os = "windows")]
#[cfg(target_arch = "x86_64")]
fn main() {
......@@ -45,9 +49,14 @@ fn main() {
.compile("libswap_stack.a");
}
#[cfg(feature = "sel4-rumprun")]
//#[cfg(all(target_os = "netbsd", target_vendor = "rumprun"))]
#[cfg(feature = "sel4-rumprun-target-side")]
#[cfg(target_arch = "x86_64")]
fn main() {
// env::set_var("ZEBU_TARGET", "x86_64-rumprun-netbsd");
// println!("*****ENV VAR SET*****");
use std::path::Path;
let mut compiler_name = String::new();
compiler_name.push_str("x86_64-rumprun-netbsd-gcc");
gcc::Config::new().flag("-O3").flag("-c")
......@@ -56,10 +65,10 @@ fn main() {
.compile("libruntime.a");
gcc::Config::new().flag("-O3").flag("-c")
.compiler(Path::new(compiler_name.as_str()))
.file("src/runtime/swap_stack_x64_sysv.S")
.file("src/runtime/swap_stack_x64_sel4_rumprun_sysv.S")
.compile("libswap_stack.a");
gcc::Config::new().flag("-O3").flag("-c")
.compiler(Path::new(compiler_name.as_str()))
.file("c_helpers.c")
.compile("libc_helpers.a");
.file("zebu_c_helpers.c")
.compile("libzebu_c_helpers.a");
}
\ No newline at end of file
#!/usr/bin/env bash
export ZEBU_TARGET=x86_64-rumprun-netbsd
cd ././../rumprun-sel4/
bash clean_and_build.sh
\ No newline at end of file
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// a pointer to asm label of serialized vm
//extern void* vm;
// a pointer to the symbol table I generate
extern void* mu_sym_table_root;
void * mu_sym_table = NULL;
extern int32_t mu_retval;
int32_t muentry_get_retval(){
return mu_retval;
}
unsigned long * get_sym_table_root(){
return (unsigned long *) &mu_sym_table_root;
}
char * get_sym_table_pointer(){
return (char *) &mu_sym_table;
}
// a function to return a pointer to serialized vm, to rust
char * get_vm_pointer(unsigned long idx){
unsigned long * current_root = get_sym_table_root();
if(current_root == NULL){
printf("get_vm_pointer: SYM TABLE ROOT IS NULL\n\n");
assert(0);
}
unsigned long ii;
// get the total number of idXs
unsigned long num_of_idXs = (unsigned long) current_root[0];
// go to next unsigned long, which is the first idX
current_root++;
for (ii=0; ii<num_of_idXs; ii++){
if( current_root[0] == idx){
return current_root[2];
}
else{
current_root += 4;
}
}
return NULL;
}
// This function returns 0 if test type is integer and 1 if test type is float
// for integer tests use =>
// get_input_value(,,)
// get_output_value(,,)
// for float tests use =>
// get_fp_input_value(,,)
// get_fp_output_value(,,)
// And these functions are common for both types =>
// get_number_of_testcases()
// get_number_of_input()
// get_number_of_outputs()
unsigned long get_type_of_testcases(unsigned long test_index){
unsigned long * current_root = get_sym_table_root();
if(current_root == NULL){
printf("get_type_of_testcases: SYM TABLE ROOT IS NULL\n\n");
assert(0);
}
unsigned long ii;
// get the total number of idXs
unsigned long num_of_idXs = (unsigned long) current_root[0];
// go to next unsigned long, which is the first idX
current_root++;
for (ii=0; ii<num_of_idXs; ii++){
if( current_root[0] == test_index){
// pointer to testcase data for current test_index is found
unsigned long * test_root = (unsigned long *) current_root[3];
unsigned long type_of_testcases = test_root[0];
unsigned long number_of_testcases = test_root[1]; // first cell is the number of testcases
unsigned long number_of_inputs = test_root[2]; // second cell is the number of inputs for this test
unsigned long number_of_outputs = test_root[3];
return type_of_testcases;
}
else{
current_root += 4;
}
}
return 0;
}
unsigned long get_number_of_testcases(unsigned long test_index){
unsigned long * current_root = get_sym_table_root();
if(current_root == NULL){
printf("get_number_of_testcases: SYM TABLE ROOT IS NULL\n\n");
assert(0);
}
unsigned long ii;
// get the total number of idXs
unsigned long num_of_idXs = (unsigned long) current_root[0];
// go to next unsigned long, which is the first idX
current_root++;
for (ii=0; ii<num_of_idXs; ii++){
if( current_root[0] == test_index){
// pointer to testcase data for current test_index is found
unsigned long * test_root = (unsigned long *) current_root[3];
unsigned long type_of_testcases = test_root[0];
unsigned long number_of_testcases = test_root[1]; // first cell is the number of testcases
unsigned long number_of_inputs = test_root[2]; // second cell is the number of inputs for this test
unsigned long number_of_outputs = test_root[3];
return number_of_testcases;
}
else{
current_root += 4;
}
}
return 0;
}
unsigned long get_number_of_inputs(unsigned long test_index){
unsigned long * current_root = get_sym_table_root();
if(current_root == NULL){
printf("get_number_of_inputs: SYM TABLE ROOT IS NULL\n\n");
assert(0);
}
unsigned long ii;
// get the total number of idXs
unsigned long num_of_idXs = (unsigned long) current_root[0];
// go to next unsigned long, which is the first idX
current_root++;
for (ii=0; ii<num_of_idXs; ii++){
if( current_root[0] == test_index){
// pointer to testcase data for current test_index is found
unsigned long * test_root = (unsigned long *) current_root[3];
unsigned long number_of_testcases = test_root[1]; // first cell is the number of testcases
unsigned long number_of_inputs = test_root[2]; // second cell is the number of inputs for this test
unsigned long number_of_outputs = test_root[3];
return number_of_inputs;
}
else{
current_root += 4;
}
}
return 0;
}
unsigned long get_number_of_outputs(unsigned long test_index){
unsigned long * current_root = get_sym_table_root();
if(current_root == NULL){
printf("get_number_of_outputs: SYM TABLE ROOT IS NULL\n\n");
assert(0);
}
unsigned long ii;
// get the total number of idXs
unsigned long num_of_idXs = (unsigned long) current_root[0];
// go to next unsigned long, which is the first idX
current_root++;
for (ii=0; ii<num_of_idXs; ii++){
if( current_root[0] == test_index){
// pointer to testcase data for current test_index is found
unsigned long * test_root = (unsigned long *) current_root[3];
unsigned long number_of_testcases = test_root[0]; // first cell is the number of testcases
unsigned long number_of_inputs = test_root[1]; // second cell is the number of inputs for this test
unsigned long number_of_outputs = test_root[2];
return number_of_outputs;
}
else{
current_root += 4;
}
}
return 0;
}
// specific to integer tests
long get_input_value(unsigned long test_index, unsigned long testcase_index, unsigned long input_index){
unsigned long * current_root = get_sym_table_root();
if(current_root == NULL){
printf("get_input_value: SYM TABLE ROOT IS NULL\n\n");
assert(0);
}
unsigned long ii;
// get the total number of idXs
unsigned long num_of_idXs = (unsigned long) current_root[0];
// go to next unsigned long, which is the first idX
current_root++;
for (ii=0; ii<num_of_idXs; ii++){
if( current_root[0] == test_index){
// pointer to testcase data for current test_index is found
unsigned long * test_root = (unsigned long *) current_root[3];
unsigned long number_of_testcases = test_root[1]; // first cell is the number of testcases
unsigned long number_of_inputs = test_root[2]; // second cell is the number of inputs for this test
unsigned long number_of_outputs = test_root[3];
if ( testcase_index < (number_of_testcases+1) ){
unsigned long exact_index = 4;
exact_index += (testcase_index) * (number_of_inputs+number_of_outputs);
exact_index += (input_index - 1);
return test_root[exact_index];
}
else{
printf("get_input_value: testcase_index out of range!\n");
return 0;
}
}
else{
current_root += 4;
}
}
return 0;
}
int get_output_value(unsigned long test_index, unsigned long testcase_index){
unsigned long * current_root = get_sym_table_root();
if(current_root == NULL){
printf("get_output_value: SYM TABLE ROOT IS NULL\n\n");
assert(0);
}
unsigned long ii;
// get the total number of idXs
unsigned long num_of_idXs = (unsigned long) current_root[0];
// go to next unsigned long, which is the first idX
current_root++;
for (ii=0; ii<num_of_idXs; ii++){
if( current_root[0] == test_index){
// pointer to testcase data for current test_index is found
unsigned long * test_root = (unsigned long *) current_root[3];
unsigned long number_of_testcases = test_root[1]; // first cell is the number of testcases
unsigned long number_of_inputs = test_root[2]; // second cell is the number of inputs for this test
unsigned long number_of_outputs = test_root[3];
// for tests which don't have a return value
if (number_of_testcases == 0)
return 0;
if ( testcase_index < (number_of_testcases) ){
unsigned long exact_index = 4;
exact_index += (testcase_index) * (number_of_inputs+number_of_outputs);
exact_index += (number_of_inputs);
return test_root[exact_index];
}
else{
printf("get_output_value: testcase_index out of range!\n");
// printf("%d\n", testcase_index);
return 0;
}
}
else{
current_root += 4;
}
}
return 0;
}
// specific to float tests
double get_fp_input_value(unsigned long test_index, unsigned long testcase_index, unsigned long input_index){
unsigned long * current_root = get_sym_table_root();
if(current_root == NULL){
printf("get_input_value: SYM TABLE ROOT IS NULL\n\n");
assert(0);
}
unsigned long ii;
// get the total number of idXs
unsigned long num_of_idXs = (unsigned long) current_root[0];
// go to next unsigned long, which is the first idX
current_root++;
for (ii=0; ii<num_of_idXs; ii++){
if( current_root[0] == test_index){
// pointer to testcase data for current test_index is found
unsigned long * test_root = (unsigned long *) current_root[3];
unsigned long number_of_testcases = test_root[1]; // first cell is the number of testcases
unsigned long number_of_inputs = test_root[2]; // second cell is the number of inputs for this test
unsigned long number_of_outputs = test_root[3];
double * fp_test_root = (double *)(&test_root[4]);
if ( testcase_index < (number_of_testcases+1) ){
unsigned long exact_index = 0;
exact_index += (testcase_index) * (number_of_inputs+number_of_outputs);
exact_index += (input_index - 1);
return fp_test_root[exact_index];
}
else{
printf("get_fp_input_value: testcase_index out of range!\n");
return 0;
}
}
else{
current_root += 4;
}
}
return 0;
}
double get_fp_output_value(unsigned long test_index, unsigned long testcase_index){
unsigned long * current_root = get_sym_table_root();
if(current_root == NULL){
printf("get_output_value: SYM TABLE ROOT IS NULL\n\n");
assert(0);
}
unsigned long ii;
// get the total number of idXs
unsigned long num_of_idXs = (unsigned long) current_root[0];
// go to next unsigned long, which is the first idX
current_root++;
for (ii=0; ii<num_of_idXs; ii++){
if( current_root[0] == test_index){
// pointer to testcase data for current test_index is found
unsigned long * test_root = (unsigned long *) current_root[3];
unsigned long number_of_testcases = test_root[1]; // first cell is the number of testcases
unsigned long number_of_inputs = test_root[2]; // second cell is the number of inputs for this test
unsigned long number_of_outputs = test_root[3];
double * fp_test_root = (double *)(&test_root[4]);
// for tests which don't have a return value
if (number_of_testcases == 0)
return 0;
if ( testcase_index < (number_of_testcases) ){
unsigned long exact_index = 0;
exact_index += (testcase_index) * (number_of_inputs+number_of_outputs);
exact_index += (number_of_inputs);
return fp_test_root[exact_index];
}
else{
printf("get_output_value: testcase_index out of range!\n");
// printf("%d\n", testcase_index);
return 0;
}
}
else{
current_root += 4;
}
}
return 0;
}
unsigned long get_number_of_tests(){
unsigned long * current_root = get_sym_table_root();
if(current_root == NULL){
printf("get_number_of_tests: SYM TABLE ROOT IS NULL\n\n");
assert(0);
}
return (unsigned long) current_root[0];
}
// a function to resolve symbol names to their address, using mu_sym_table\
// which is valued by the c_resolve_sym function, according to \
// mu_sym_table_root
// actually this function will search for the symbol in one idX_sym_table
void * resolve_symbol_in_current_context(const unsigned char * input_symbol_name){
unsigned long i = 0, j=0;
unsigned long num_of_syms = 0;
unsigned long cur_len = 0;
unsigned long input_len = 0;
unsigned char cur_char = 0;
unsigned long cur_add = 0;
unsigned char is_different = 0;
while(input_symbol_name[input_len] != 0){
input_len++;
}
if( (mu_sym_table == NULL) || (input_len == 0)){
printf("**********\n****ERROR!!!****\nC_RESOLVE_SYMBOL: extern mu sym table is null!\n*********\n");
assert(0);
}
// a copy of mu_sym_table, to keep mu_sym_table from changing
// unsigned char * sym_table_current = (unsigned char *) get_sym_table_pointer();
unsigned char * sym_table_current = (unsigned char *) mu_sym_table;
// printf("C_RESOLVE_SYMBOL --> Step 1\n");
// printf("C_RESOLVE_SYMBOL --> Current mu_sym_table = %p\n", sym_table_current);
// printf("C_RESOLVE_SYMBOL --> Current vm = %p\n", get_vm_pointer());
// read the total number of symbols from the first line of sym table
num_of_syms = *((unsigned long*)sym_table_current);
// printf("RESOLVE_SYM --> number of symbols = %d\n", num_of_syms);
// go 8 bytes forward, to skip the current .quad
sym_table_current += 8;
for(i=0; i<num_of_syms; i++){
is_different = 0;
// length of the symbol we are going to check
cur_len = *((unsigned long*)sym_table_current);
if(cur_len != input_len){
sym_table_current += 8; //cur_len
sym_table_current += 8; //cur_add
sym_table_current += cur_len; //length of cur_name
// printf("*** Sym name doesn't match! ***\n");
continue;
}
sym_table_current += 8;
// printf("Sym_Tbl current Len = %d\n", cur_len);
for(j=0; j<cur_len; j++){
cur_char = *((unsigned char*)sym_table_current);
sym_table_current += 1;
// printf("Sym_Tbl read char = %d , input symbol current char = %d\n", cur_char, input_symbol_name[j]);
if(cur_char == input_symbol_name[j]){
continue;
}
else{
is_different = 1;
sym_table_current += ((cur_len-j)-1);
break;
}
}
if(is_different == 1){
// skip the 64b address in current location and continue to the next sym in table
// printf("*** Sym name doesn't match! ***\n");
sym_table_current += 8;
continue;
}
else{
// printf("*** Sym name = %s! Sym Address = %llu***\n", input_symbol_name, *((long*) sym_table_current));
// printf("*** Last char = %c\n", sym_table_current[-1]);
// for(j=0; j<8; j++){
// printf("*** Last char = %c\n", sym_table_current[j]);
// }
unsigned long result = 0;
unsigned long shifter=1;
unsigned int ii=0, jj=0;
for (ii=0; ii<8; ii++){
shifter = 1;
for(jj=0; jj<ii; jj++)
shifter = shifter * 256;
result += ((sym_table_current[ii]%256)* shifter);
// printf("Char = %x\n", (sym_table_current[ii]%256));
// printf("Result = %llu\n", result);
}
// printf("*** going to return {-%llu-}\n", result);
return ((void*) result);
}
}
return NULL;
}
void * c_resolve_symbol(const unsigned char * input_symbol_name){
unsigned long * current_root = get_sym_table_root();
if(current_root == NULL){
printf("c_resolve_symbol: SYM TABLE ROOT IS NULL\n\n");
assert(0);
}
unsigned long idX = 0;
unsigned long ii;
unsigned long * table_pointer = NULL;
// get the total number of idXs
unsigned long num_of_idXs = (unsigned long) current_root[0];
// go to next unsigned long, which is the first idX
current_root++;
for (ii=0; ii<num_of_idXs; ii++){
idX = current_root[0];
table_pointer = current_root[1];
mu_sym_table = table_pointer;
table_pointer = resolve_symbol_in_current_context(input_symbol_name);
if(table_pointer == NULL){
current_root += 4;
continue;
}
break;
}
return table_pointer;
}
......@@ -802,7 +802,7 @@ impl Value {
}
const DISPLAY_ID : bool = true;
const DISPLAY_TYPE : bool = false;
const DISPLAY_TYPE : bool = true;
const PRINT_ABBREVIATE_NAME: bool = true;
impl fmt::Debug for Value {
......
......@@ -2790,6 +2790,7 @@ fn write_const_value(f: &mut File, constant: P<Value>) {
}
}
use std::collections::HashMap;
pub fn emit_context_with_reloc(vm: &VM,
......
......@@ -15,6 +15,7 @@
#![allow(unused_variables)]
use compiler::backend::AOT_EMIT_CONTEXT_FILE;
use compiler::backend::AOT_EMIT_SYM_TABLE_FILE;
use compiler::backend::RegGroup;
use utils::ByteSize;
use utils::Address;
......@@ -2998,6 +2999,7 @@ impl CodeGenerator for ASMCodeGen {
self.add_asm_branch2(asm, dest_name);
}
#[cfg(not(feature = "sel4-rumprun"))]
#[cfg(target_os = "macos")]
fn emit_call_near_rel32(&mut self, callsite: String, func: MuName, pe: Option<MuName>) -> ValueLocation {
trace!("emit: call {}", func);
......@@ -3012,6 +3014,7 @@ impl CodeGenerator for ASMCodeGen {
ValueLocation::Relocatable(RegGroup::GPR, callsite)
}
#[cfg(not(feature = "sel4-rumprun"))]
#[cfg(target_os = "linux")]
// generating Position-Independent Code using PLT
fn emit_call_near_rel32(&mut self, callsite: String, func: MuName, pe: Option<MuName>) -> ValueLocation {
......@@ -3436,11 +3439,14 @@ fn write_const_min_align(f: &mut File) {
write_align(f, MIN_ALIGN);
}
#[cfg(not(feature = "sel4-rumprun"))]
#[cfg(target_os = "linux")]
fn write_align(f: &mut File, align: ByteSize) {
use std::io::Write;
f.write_fmt(format_args!("\t.align {}\n", check_min_align(align))).unwrap();
}
#[cfg(not(feature = "sel4-rumprun"))]
#[cfg(target_os = "macos")]
fn write_align(f: &mut File, align: ByteSize) {
use std::io::Write;
......@@ -3524,6 +3530,128 @@ fn write_const_value(f: &mut File, constant: P<Value>) {
}
}
#[cfg(not(feature = "sel4-rumprun"))]
pub fn emit_sym_table(vm: &VM) {
debug!("Currently nothing to emit for --!");
}
#[cfg(feature = "sel4-rumprun")]
pub fn emit_sym_table(vm: &VM){
use std::path;
use std::io::Write;
// Javad-cross-compile
// code to generate an asm file to resolve symbol addresses at link time!
// in this stage, a single sym_file is generated for each test
// these sym_files will be merged in build.rs\
// in the parent directory of sel4 side
//**************************************************
// Code starts here
// first create the asm file in the correct path
// _st added file name and path stands for _SymTable
// *************************************************
debug!("Going to emit Sym table for sel4-rumprun");
let mut file_path_st = path::PathBuf::new();
file_path_st.push(&vm.vm_options.flag_aot_emit_dir);
//just the file name is changed compared to context.s
// vm file name is: "fnID_sym_table.s"
file_path_st.push(format!("{}", AOT_EMIT_SYM_TABLE_FILE));
let mut file_st = match File::create(file_path_st.as_path()) {
Err(why) => panic!("couldn't create SYM TABLE file {}: {}", file_path_st.to_str().unwrap(), why),
Ok(file) => file
};
// **************************************************
// fnID_sym_table.s is created, but it's empty
// *************************************************
// **************************************************
// Code for exporting all of the required symbols \
// in vm, using the following fields:
// compiled_funcs.CompiledFunction.start
// compiled_funcs.CompiledFunction.end
// compiled_funcs.CompiledFunction.Frame. \
// exception_callsites[iter](src,_)
// compiled_funcs.CompiledFunction.Frame. \
// exception_callsites[iter](_,dest)
// ret
// *************************************************
let mut sym_vec: Vec<String> = Vec::new();
let compiled_funcs : &HashMap<_, _> = &vm.compiled_funcs().read().unwrap();
debug!("Number of Compiled functions: {}\n", compiled_funcs.len());
for (theID, theCFs) in compiled_funcs.iter() {
let theCF : &CompiledFunction = &theCFs.read().unwrap();
debug!("new theCF\n");
match theCF.start {
// CF.start can only be relocatable , otherwise panic
ValueLocation::Relocatable(_, ref symbol) => {
debug!("theCF.start, symbol = {}\n", *symbol);
sym_vec.push((*symbol).clone());
},
// CF.start can't reach this state
_ => panic!("Sym_Table_start: expecting Relocatable location, found {}", theCF.start)
}
match theCF.end {
// CF.start can only be relocatable , otherwise panic
ValueLocation::Relocatable(_, ref symbol) => {
debug!("theCF.end, symbol = {}\n", *symbol);
sym_vec.push((*symbol).clone());
},
// CF.end can't reach this state
_ => panic!("Sym_Table_end: expecting Relocatable location, found {}", theCF.end)