macsim/src/arch/rvmpb.c
// ---------------------------------------------------------------------
// Main switch for decoding and execution
// ---------------------------------------------------------------------
Main switch for decoding and execution
Main switch for decoding and execution
instruction_class_t rvmpb_execute_iw(node_t *node, uint_fast32_t iw, uint_fast32_t next_iw)
{
    uf32_t x32;
    uf64_t x64;
    node->core.riscv.reg[0] = 0;
    if ((iw&0x5b)==0x03) switch (iw & 0x7f)
    {
        case 0x03:
        {
            addr_t addr = REG_S + IMM_I;
            instruction_class_t latency = RVMPB_LATENCY_ADDR_CALC;
            if (riscv_instruction_uses_reg_s(next_iw) && nBRu(19, 15) == BRu(11, 7)) {
                latency = RVMPB_LATENCY_INTERLOCK;
            }
            if (riscv_instruction_uses_reg_t(next_iw) && nBRu(24, 20) == BRu(11, 7)) {
                latency = RVMPB_LATENCY_INTERLOCK;
            }
            uint_fast16_t op = (iw >> 12) & 7;
            if (op!=7) {
                unsigned access_from_opcode[8] =
                    {MA_8, MA_16le, MA_32le, MA_64le, MA_u8, MA_u16le, MA_u32le, 0};
                instruction_class_t ic = 
                    memory_load_u64(node, access_from_opcode[op], addr, &REG_Du);
                return (ic<0) ? ic : (ic+latency);
            }
            break;
        }
        case 0x23:
        {
            addr_t addr = REG_S + IMM_S;
            switch (iw & 0x7000) {
            case 0x0000: return RVMPB_LATENCY_ADDR_CALC
                + memory_store(node, MA_8, addr, REG_Tu); 
            case 0x1000: return RVMPB_LATENCY_ADDR_CALC
                + memory_store(node, MA_16le, addr, REG_Tu); 
            case 0x2000: return RVMPB_LATENCY_ADDR_CALC
                + memory_store(node, MA_32le, addr, REG_Tu); 
            case 0x3000: return RVMPB_LATENCY_ADDR_CALC
                + memory_store(node, MA_64le, addr, REG_Tu); 
            }
            break;
        }
        case 0x07:
        {
            addr_t addr = REG_S + IMM_I;
            switch (iw & 0x7000) {
            case 0x2000:  
            {
                uint64_t u;
                uint16_t lat = memory_load_u64(node, MA_32le, addr, &u);
                x32.i = u;
                DREG_D = boxing_float(x32.f);
                return RVMPB_LATENCY_ADDR_CALC+lat;
            }
            case 0x3000:  
            {
                uint16_t lat = memory_load_u64(node, MA_64le, addr, &x64.u);
                DREG_D = x64.f;
                return RVMPB_LATENCY_ADDR_CALC+lat;
            }
            }
            break;
        }
        case 0x27:
        {
            addr_t addr = REG_S + IMM_S;
            switch (iw & 0x7000) {
            case 0x2000:  
                x32.f = unboxing_float(DREG_T);
                return RVMPB_LATENCY_ADDR_CALC
                    + memory_store(node, MA_32le, addr, x32.i);
            case 0x3000:  
                x64.f = DREG_T;
                return RVMPB_LATENCY_ADDR_CALC
                    + memory_store(node, MA_64le, addr, x64.u);
            }
            break;
        }
    }
    if ((iw&0x707f)==0x206b) {
        node->core.riscv.loadbuf_rank = conf_max_rank;
        return 1;
    }
    return riscv_execute_iw(node, iw, next_iw);
}
instruction_class_t rvmpb_execute_iw ( node_t * node , uint_fast32_t iw , uint_fast32_t next_iw ) { uf32_t x32 ; uf64_t x64 ; node -> core . riscv . reg [ 0 ] = 0 ; if ( ( iw & 0x5b ) == 0x03 ) switch ( iw & 0x7f ) { case 0x03 : { addr_t addr = REG_S + IMM_I ; instruction_class_t latency = RVMPB_LATENCY_ADDR_CALC ; if ( riscv_instruction_uses_reg_s ( next_iw ) && nBRu ( 19 , 15 ) == BRu ( 11 , 7 ) ) { latency = RVMPB_LATENCY_INTERLOCK ; } if ( riscv_instruction_uses_reg_t ( next_iw ) && nBRu ( 24 , 20 ) == BRu ( 11 , 7 ) ) { latency = RVMPB_LATENCY_INTERLOCK ; } uint_fast16_t op = ( iw >> 12 ) & 7 ; if ( op != 7 ) { unsigned access_from_opcode [ 8 ] = { MA_8 , MA_16le , MA_32le , MA_64le , MA_u8 , MA_u16le , MA_u32le , 0 } ; instruction_class_t ic = memory_load_u64 ( node , access_from_opcode [ op ] , addr , & REG_Du ) ; return ( ic < 0 ) ? ic : ( ic + latency ) ; } break ; } case 0x23 : { addr_t addr = REG_S + IMM_S ; switch ( iw & 0x7000 ) { case 0x0000 : return RVMPB_LATENCY_ADDR_CALC + memory_store ( node , MA_8 , addr , REG_Tu ) ; case 0x1000 : return RVMPB_LATENCY_ADDR_CALC + memory_store ( node , MA_16le , addr , REG_Tu ) ; case 0x2000 : return RVMPB_LATENCY_ADDR_CALC + memory_store ( node , MA_32le , addr , REG_Tu ) ; case 0x3000 : return RVMPB_LATENCY_ADDR_CALC + memory_store ( node , MA_64le , addr , REG_Tu ) ; } break ; } case 0x07 : { addr_t addr = REG_S + IMM_I ; switch ( iw & 0x7000 ) { case 0x2000 : { uint64_t u ; uint16_t lat = memory_load_u64 ( node , MA_32le , addr , & u ) ; x32 . i = u ; DREG_D = boxing_float ( x32 . f ) ; return RVMPB_LATENCY_ADDR_CALC + lat ; } case 0x3000 : { uint16_t lat = memory_load_u64 ( node , MA_64le , addr , & x64 . u ) ; DREG_D = x64 . f ; return RVMPB_LATENCY_ADDR_CALC + lat ; } } break ; } case 0x27 : { addr_t addr = REG_S + IMM_S ; switch ( iw & 0x7000 ) { case 0x2000 : x32 . f = unboxing_float ( DREG_T ) ; return RVMPB_LATENCY_ADDR_CALC + memory_store ( node , MA_32le , addr , x32 . i ) ; case 0x3000 : x64 . f = DREG_T ; return RVMPB_LATENCY_ADDR_CALC + memory_store ( node , MA_64le , addr , x64 . u ) ; } break ; } } if ( ( iw & 0x707f ) == 0x206b ) { node -> core . riscv . loadbuf_rank = conf_max_rank ; return 1 ; } return riscv_execute_iw ( node , iw , next_iw ) ; }
Main switch for decoding and execution
Main switch for decoding and execution
// next_instruction.REG_S = REG_D and next_instruction uses REG_S // next_instruction.REG_T = REG_D and next_instruction uses REG_T // sb // sh // sw // sd // flw // fld // fsw // fsd // invmpb