#ifdef SYSTEMC /* * $Id: Operation.cpp 88 2008-12-10 18:31:39Z rosiere $ * * [ Description ] * */ #include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Functionnal_unit/Operation/include/Operation.h" #include "Behavioural/include/Operation.h" namespace morpheo { namespace behavioural { namespace core { namespace multi_execute_loop { namespace execute_loop { namespace multi_execute_unit { namespace execute_unit { namespace functionnal_unit { #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_unimplemented" void operation_unimplemented (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : unimplemented"); throw ERRORMORPHEO(FUNCTION,"The operation '"+toString(op->_operation)+"' is not implemented in this Functionnal_unit"); }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_add" void operation_l_add (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_add"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); Tgeneral_data_t gpr3 = param->_mask_data & (gpr1 + gpr2); bool overflow = ovf (param->_size_data,gpr1,gpr2,gpr3); bool carry_out = carry(param->_size_data,gpr1,gpr2,gpr3); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr3; op->_data_re = 0; op->_data_re = set_flag(op->_data_re,FLAG_OV,overflow ); op->_data_re = set_flag(op->_data_re,FLAG_CY,carry_out); op->_exception = (overflow==1)?EXCEPTION_ALU_RANGE:EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_addc" void operation_l_addc (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_addc"); Tgeneral_data_t carry_in = get_flag(op->_data_rc,FLAG_CY); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); Tgeneral_data_t gpr3 = param->_mask_data & (gpr1 + gpr2 + carry_in); bool overflow = ovf (param->_size_data,gpr1,gpr2,gpr3); bool carry_out = carry(param->_size_data,gpr1,gpr2,gpr3); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr3; op->_data_re = 0; op->_data_re = set_flag(op->_data_re,FLAG_OV,overflow ); op->_data_re = set_flag(op->_data_re,FLAG_CY,carry_out); op->_exception = (overflow==1)?EXCEPTION_ALU_RANGE:EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_sub" void operation_l_sub (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_sub"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = neg(param->_size_data,unsigned(param->_size_data,op->_data_rb)); Tgeneral_data_t gpr3 = param->_mask_data & (gpr1 + gpr2); bool overflow = ovf (param->_size_data,gpr1,gpr2,gpr3); bool carry_out = carry(param->_size_data,gpr1,gpr2,gpr3); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr3; op->_data_re = 0; op->_data_re = set_flag(op->_data_re,FLAG_OV,overflow ); op->_data_re = set_flag(op->_data_re,FLAG_CY,carry_out); op->_exception = (overflow==1)?EXCEPTION_ALU_RANGE:EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_and" void operation_l_and (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_and"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); Tgeneral_data_t gpr3 = (gpr1 & gpr2); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr3; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_or" void operation_l_or (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_or"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); Tgeneral_data_t gpr3 = (gpr1 | gpr2); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr3; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_xor" void operation_l_xor (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_xor"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); Tgeneral_data_t gpr3 = (gpr1 ^ gpr2); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr3; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_movhi" void operation_l_movhi (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_movhi"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_immediat); Tgeneral_data_t gpr2 = param->_mask_data & (gpr1<<16); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr2; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_cmov" void operation_l_cmov (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_cmov"); Tgeneral_data_t f_in = get_flag(op->_data_rc,FLAG_F); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,op->_data_rb); Tgeneral_data_t gpr3 = ((f_in==0)?gpr2:gpr1); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr3; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_test_f" void operation_l_test_f (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_test_f"); Tgeneral_data_t f_in = get_flag(op->_data_rc,FLAG_F); Tgeneral_data_t imm = unsigned(param->_size_data,op->_immediat); // Result op->_timing = param->_timing[op->_type][op->_operation]; //op->_data_rd = 0; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = f_in != 0; op->_address = imm; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_test_nf" void operation_l_test_nf (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_test_nf"); Tgeneral_data_t f_in = get_flag(op->_data_rc,FLAG_F); Tgeneral_data_t imm = unsigned(param->_size_data,op->_immediat); // Result op->_timing = param->_timing[op->_type][op->_operation]; //op->_data_rd = 0; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = f_in == 0; op->_address = imm; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_jalr" void operation_l_jalr (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_jalr"); // jal : has_imm = 1, write_rd = 1, read_rb = 0 // jalr : has_imm = 1, write_rd = 1, read_rb = 1 // jr : has_imm = 0, write_rd = 0, read_rb = 1 Tgeneral_data_t gpr = unsigned(param->_size_data,op->_data_rb); Tgeneral_data_t imm = unsigned(param->_size_data,op->_immediat); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = imm; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 1; op->_address = gpr; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_extend_s" void operation_l_extend_s (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_extend_s"); Tgeneral_data_t imm = unsigned(param->_size_data,op->_immediat); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = extend(param->_size_data, gpr1, true , imm); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr2; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_extend_z" void operation_l_extend_z (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_extend_z"); Tgeneral_data_t imm = unsigned(param->_size_data,op->_immediat); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = extend(param->_size_data, gpr1, false , imm); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr2; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_sll" void operation_l_sll (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_sll"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = param->_mask_shift & unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); Tgeneral_data_t gpr3 = shift_logic_left(param->_size_data, gpr1, gpr2); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr3; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_srl" void operation_l_srl (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_srl"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = param->_mask_shift & unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); Tgeneral_data_t gpr3 = shift_logic_right(param->_size_data, gpr1, gpr2); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr3; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_sra" void operation_l_sra (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_sra"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = param->_mask_shift & unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); Tgeneral_data_t gpr3 = shift_arithmetic_right(param->_size_data, gpr1, gpr2); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr3; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_ror" void operation_l_ror (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_ror"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = param->_mask_shift & unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); Tgeneral_data_t gpr3 = rotate_right(param->_size_data, gpr1, gpr2); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr3; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_ff1" void operation_l_ff1 (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_ff1"); Tgeneral_data_t gpr = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t index; for (index=0; (index_size_data) and (((gpr>>index)&1)!= 1); index++); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = (index==param->_size_data)?0:(index+1); //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_fl1" void operation_l_fl1 (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_fl1"); Tgeneral_data_t gpr = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t index; for (index=param->_size_data; (index>0) and (((gpr>>(index-1))&1)!= 1); index--); // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = index; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_sfeq" void operation_l_sfeq (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_sfeq"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); bool f_out = (gpr1 == gpr2); // Result op->_timing = param->_timing[op->_type][op->_operation]; //op->_data_rd = 0; op->_data_re = set_flag(op->_data_re,FLAG_F,f_out); op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_sfne" void operation_l_sfne (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_sfne"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); bool f_out = (gpr1 != gpr2); // Result op->_timing = param->_timing[op->_type][op->_operation]; //op->_data_rd = 0; op->_data_re = set_flag(op->_data_re,FLAG_F,f_out); op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_sfgeu" void operation_l_sfgeu (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_sfgeu"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); bool f_out = (gpr1 >= gpr2); // Result op->_timing = param->_timing[op->_type][op->_operation]; //op->_data_rd = 0; op->_data_re = set_flag(op->_data_re,FLAG_F,f_out); op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_sfgtu" void operation_l_sfgtu (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_sfgtu"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); bool f_out = (gpr1 > gpr2); // Result op->_timing = param->_timing[op->_type][op->_operation]; //op->_data_rd = 0; op->_data_re = set_flag(op->_data_re,FLAG_F,f_out); op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_sfleu" void operation_l_sfleu (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_sfleu"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); bool f_out = (gpr1 <= gpr2); // Result op->_timing = param->_timing[op->_type][op->_operation]; //op->_data_rd = 0; op->_data_re = set_flag(op->_data_re,FLAG_F,f_out); op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_sfltu" void operation_l_sfltu (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_sfltu"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); bool f_out = (gpr1 < gpr2); // Result op->_timing = param->_timing[op->_type][op->_operation]; //op->_data_rd = 0; op->_data_re = set_flag(op->_data_re,FLAG_F,f_out); op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_sfges" void operation_l_sfges (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_sfges"); Tgeneral_data_t gpr1 = op->_data_ra; Tgeneral_data_t gpr2 = (op->_has_immediat==1)?op->_immediat:op->_data_rb; log_printf(TRACE,Functionnal_unit,FUNCTION," * data_ra : %.8x",unsigned(param->_size_data,op->_data_ra)); log_printf(TRACE,Functionnal_unit,FUNCTION," * data_ras : %.8x", signed(param->_size_data,op->_data_ra)); log_printf(TRACE,Functionnal_unit,FUNCTION," * data_rb : %.8x",unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb)); log_printf(TRACE,Functionnal_unit,FUNCTION," * data_rbs : %.8x", signed(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb)); bool f_out; switch (concatenation_bool(sign(param->_size_data,gpr1),sign(param->_size_data,gpr2))) { case 1 /*b01*/ : f_out = 1 ; break; case 2 /*b10*/ : f_out = 0 ; break; default : f_out = signed(param->_size_data,gpr1) >= signed(param->_size_data,gpr2); break; } log_printf(TRACE,Functionnal_unit,FUNCTION," * f_out : %.8x",f_out); // Result op->_timing = param->_timing[op->_type][op->_operation]; //op->_data_rd = 0; op->_data_re = set_flag(op->_data_re,FLAG_F,f_out); op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_sfgts" void operation_l_sfgts (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_sfgts"); Tgeneral_data_t gpr1 = op->_data_ra ; Tgeneral_data_t gpr2 = (op->_has_immediat==1)?op->_immediat:op->_data_rb ; bool f_out; switch (concatenation_bool(sign(param->_size_data,gpr1),sign(param->_size_data,gpr2))) { case 1 /*b01*/ : f_out = 1; break; case 2 /*b10*/ : f_out = 0; break; default : f_out = signed(param->_size_data,gpr1) > signed(param->_size_data,gpr2); break; } // Result op->_timing = param->_timing[op->_type][op->_operation]; //op->_data_rd = 0; op->_data_re = set_flag(op->_data_re,FLAG_F,f_out); op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_sfles" void operation_l_sfles (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_sfles"); Tgeneral_data_t gpr1 = op->_data_ra ; Tgeneral_data_t gpr2 = (op->_has_immediat==1)?op->_immediat:op->_data_rb ; bool f_out; switch (concatenation_bool(sign(param->_size_data,gpr1),sign(param->_size_data,gpr2))) { case 1 /*b01*/ : f_out = 0; break; case 2 /*b10*/ : f_out = 1; break; default : f_out = signed(param->_size_data,gpr1) <= signed(param->_size_data,gpr2); break; } // Result op->_timing = param->_timing[op->_type][op->_operation]; //op->_data_rd = 0; op->_data_re = set_flag(op->_data_re,FLAG_F,f_out); op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_sflts" void operation_l_sflts (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_sflts"); Tgeneral_data_t gpr1 = op->_data_ra ; Tgeneral_data_t gpr2 = (op->_has_immediat==1)?op->_immediat:op->_data_rb; bool f_out; switch (concatenation_bool(sign(param->_size_data,gpr1),sign(param->_size_data,gpr2))) { case 1 /*b01*/ : f_out = 0; break; case 2 /*b10*/ : f_out = 1; break; default : f_out = signed(param->_size_data,gpr1) < signed(param->_size_data,gpr2); break; } // Result op->_timing = param->_timing[op->_type][op->_operation]; //op->_data_rd = 0; op->_data_re = set_flag(op->_data_re,FLAG_F,f_out); op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_mtspr" void operation_l_mtspr (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_mtspr"); Tgeneral_data_t imm = unsigned(param->_size_data,op->_immediat); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,op->_data_rb); Tgeneral_data_t addr = range(gpr1|imm,16); Texception_t exception; // HACK : use the field num_reg_re to pass the SM and SUMRA flag. Tcontrol_t flag_SM = get_flag(op->_num_reg_re, 0x1); Tcontrol_t flag_SUMRA = get_flag(op->_num_reg_re, 0x2); spr_address_t spr_addr = reg->_spr_access_mode->translate_address(addr); // Test if this group is implemented in this functionnal_unit if (reg->_spr_access_mode->valid(spr_addr)) { if (reg->_spr_access_mode->write(spr_addr, flag_SM, flag_SUMRA)) { reg->_i_write_spr = true; reg->_access_num_group = spr_addr._group; reg->_access_num_register = spr_addr._register; reg->_spr_old = reg->_spr[spr_addr._group][spr_addr._register]; reg->_spr[spr_addr._group][spr_addr._register] = gpr2; exception = EXCEPTION_ALU_NONE; } else { exception = EXCEPTION_ALU_SPR_ACCESS_INVALID; } } else { exception = EXCEPTION_ALU_SPR_ACCESS_MUST_WRITE; } // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr2; // data_rb //op->_data_re = 0; op->_exception = exception; op->_no_sequence = 0; op->_address = addr; // data_ra or imm }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_mfspr" void operation_l_mfspr (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_mfspr"); Tgeneral_data_t imm = unsigned(param->_size_data,op->_immediat); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = 0; Tgeneral_data_t addr = range(gpr1|imm,16); Texception_t exception; // HACK : use the field num_reg_re to pass the SM and SUMRA flag. Tcontrol_t flag_SM = get_flag(op->_num_reg_re, 0x1); Tcontrol_t flag_SUMRA = get_flag(op->_num_reg_re, 0x2); spr_address_t spr_addr = reg->_spr_access_mode->translate_address(addr); // Test if this group is implemented in this functionnal_unit if (reg->_spr_access_mode->valid(spr_addr)) { if (reg->_spr_access_mode->read(spr_addr, flag_SM, flag_SUMRA)) { reg->_i_read_spr = true; reg->_access_num_group = spr_addr._group; reg->_access_num_register = spr_addr._register; gpr2 = reg->_spr[spr_addr._group][spr_addr._register]; exception = EXCEPTION_ALU_NONE; } else { exception = EXCEPTION_ALU_SPR_ACCESS_INVALID; } } else { exception = EXCEPTION_ALU_SPR_ACCESS_MUST_READ; } // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_write_rd = (exception == EXCEPTION_ALU_NONE); op->_data_rd = gpr2; // spr //op->_data_re = 0; op->_exception = exception; op->_no_sequence = 0; op->_address = addr; // data_ra or imm }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_macrc" void operation_l_macrc (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_macrc"); Tgeneral_data_t gpr = static_cast(range((static_cast(reg->_spr[GROUP_MAC][SPR_MACHI]) << 32) | static_cast(reg->_spr[GROUP_MAC][SPR_MACLO]), param->_size_data)); reg->_spr[GROUP_MAC][SPR_MACLO] = 0; reg->_spr[GROUP_MAC][SPR_MACHI] = 0; // Result op->_timing = param->_timing[op->_type][op->_operation]; op->_data_rd = gpr; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_mac" void operation_l_mac (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_mac"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); uint64_t temp = range(gpr1 * gpr2, 32); temp = ((static_cast(reg->_spr[GROUP_MAC][SPR_MACHI]) << 32) | static_cast(reg->_spr[GROUP_MAC][SPR_MACLO])) + temp; reg->_spr[GROUP_MAC][SPR_MACLO] = range(temp ,32); reg->_spr[GROUP_MAC][SPR_MACHI] = range(temp>>32,32); // Result op->_timing = param->_timing[op->_type][op->_operation]; //op->_data_rd = 0; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; #undef FUNCTION #define FUNCTION "Functionnal_unit::operation_l_msb" void operation_l_msb (execute_operation_t * op, execute_register_t * reg, execute_param_t * param) { log_printf(TRACE,Functionnal_unit,FUNCTION,"Operation : l_msb"); Tgeneral_data_t gpr1 = unsigned(param->_size_data,op->_data_ra); Tgeneral_data_t gpr2 = unsigned(param->_size_data,(op->_has_immediat==1)?op->_immediat:op->_data_rb); uint64_t temp = range(gpr1 * gpr2, 32); temp = ((static_cast(reg->_spr[GROUP_MAC][SPR_MACHI]) << 32) | static_cast(reg->_spr[GROUP_MAC][SPR_MACLO])) - temp; reg->_spr[GROUP_MAC][SPR_MACLO] = range(temp ,32); reg->_spr[GROUP_MAC][SPR_MACHI] = range(temp>>32,32); // Result op->_timing = param->_timing[op->_type][op->_operation]; //op->_data_rd = 0; //op->_data_re = 0; op->_exception = EXCEPTION_ALU_NONE; op->_no_sequence = 0; //op->_address = 0; }; }; // end namespace functionnal_unit }; // end namespace execute_unit }; // end namespace multi_execute_unit }; // end namespace execute_loop }; // end namespace multi_execute_loop }; // end namespace core }; // end namespace behavioural }; // end namespace morpheo #endif