#ifdef SYSTEMC /* * $Id$ * * [ Description ] * */ #include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Functionnal_unit/include/Operation.h" #define neg(data) (~(data)+1) #define sign(data) ((data)>>(param->_size_data-1)) #define unsigned(data) (data) #define signed(data) ((sign(data)==0)?(data):neg(data)) #define ovf(op1, op2, res) ((sign(op1) == sign(op2))?(sign(op1) xor sign(res)):0) #define carry(op1, op2, res) (((res)<(op1)) or ((res)<(op2))) #define set_flag(data,flag,is_set) (((is_set)==1)?((data)|(flag)):((data)&~(flag))) #define get_flag(data,flag) (((data)&(flag))!=0) #define concatenation_bool(a,b) (((a)<<1) | (b)) 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(op->_data_ra); Tgeneral_data_t gpr2 = unsigned((op->_has_immediat==1)?op->_immediat:op->_data_rb); Tgeneral_data_t gpr3 = param->_mask_data & (gpr1 + gpr2); bool overflow = ovf (gpr1,gpr2,gpr3); bool carry_out = carry(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(op->_data_ra); Tgeneral_data_t gpr2 = unsigned((op->_has_immediat==1)?op->_immediat:op->_data_rb); Tgeneral_data_t gpr3 = param->_mask_data & (gpr1 + gpr2 + carry_in); bool overflow = ovf (gpr1,gpr2,gpr3); bool carry_out = carry(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(op->_data_ra); Tgeneral_data_t gpr2 = neg(unsigned(op->_data_rb)); Tgeneral_data_t gpr3 = param->_mask_data & (gpr1 + gpr2); bool overflow = ovf (gpr1,gpr2,gpr3); bool carry_out = carry(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(op->_data_ra); Tgeneral_data_t gpr2 = unsigned((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(op->_data_ra); Tgeneral_data_t gpr2 = unsigned((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(op->_data_ra); Tgeneral_data_t gpr2 = unsigned((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(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(op->_data_ra); Tgeneral_data_t gpr2 = unsigned(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(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(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(op->_data_rb); Tgeneral_data_t imm = unsigned(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(op->_immediat); Tgeneral_data_t gpr1 = unsigned(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(op->_immediat); Tgeneral_data_t gpr1 = unsigned(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(op->_data_ra); Tgeneral_data_t gpr2 = param->_mask_shift & unsigned((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(op->_data_ra); Tgeneral_data_t gpr2 = param->_mask_shift & unsigned((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(op->_data_ra); Tgeneral_data_t gpr2 = param->_mask_shift & unsigned((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(op->_data_ra); Tgeneral_data_t gpr2 = param->_mask_shift & unsigned((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(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(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(op->_data_ra); Tgeneral_data_t gpr2 = unsigned((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(op->_data_ra); Tgeneral_data_t gpr2 = unsigned((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(op->_data_ra); Tgeneral_data_t gpr2 = unsigned((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(op->_data_ra); Tgeneral_data_t gpr2 = unsigned((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(op->_data_ra); Tgeneral_data_t gpr2 = unsigned((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(op->_data_ra); Tgeneral_data_t gpr2 = unsigned((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(op->_data_ra)); log_printf(TRACE,Functionnal_unit,FUNCTION," * data_ras : %.8x", signed(op->_data_ra)); log_printf(TRACE,Functionnal_unit,FUNCTION," * data_rb : %.8x",unsigned((op->_has_immediat==1)?op->_immediat:op->_data_rb)); log_printf(TRACE,Functionnal_unit,FUNCTION," * data_rbs : %.8x", signed((op->_has_immediat==1)?op->_immediat:op->_data_rb)); bool f_out; switch (concatenation_bool(sign(gpr1),sign(gpr2))) { case 1 /*b01*/ : f_out = 1 ; break; case 2 /*b10*/ : f_out = 0 ; break; default : f_out = signed(gpr1) >= signed(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(gpr1),sign(gpr2))) { case 1 /*b01*/ : f_out = 1; break; case 2 /*b10*/ : f_out = 0; break; default : f_out = signed(gpr1) > signed(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(gpr1),sign(gpr2))) { case 1 /*b01*/ : f_out = 0; break; case 2 /*b10*/ : f_out = 1; break; default : f_out = signed(gpr1) <= signed(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(gpr1),sign(gpr2))) { case 1 /*b01*/ : f_out = 0; break; case 2 /*b10*/ : f_out = 1; break; default : f_out = signed(gpr1) < signed(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(op->_immediat); Tgeneral_data_t gpr1 = unsigned(op->_data_ra); Tgeneral_data_t gpr2 = unsigned(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_NOT_COMPLETE; } // 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(op->_immediat); Tgeneral_data_t gpr1 = unsigned(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_NOT_COMPLETE; } // 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(op->_data_ra); Tgeneral_data_t gpr2 = unsigned((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(op->_data_ra); Tgeneral_data_t gpr2 = unsigned((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