コード例 #1
0
void CodeGen::gen_x_cmp(JavaByteCodes op, jtype jt)
{
    if (is_f(jt)) {
        char *helper;
        if (jt == dbl64) {
            assert(op == OPCODE_DCMPG || op == OPCODE_DCMPL);
            helper = op == OPCODE_DCMPG ? 
                                 (char*)&rt_h_dcmp_g : (char*)&rt_h_dcmp_l;
        }
        else {
            assert(op == OPCODE_FCMPG || op == OPCODE_FCMPL);
            helper = op == OPCODE_FCMPG ? 
                                 (char*)&rt_h_fcmp_g : (char*)&rt_h_fcmp_l;
        }
        const CallSig cs(CCONV_STDCALL, i32, jt, jt);
        unsigned stackFix = gen_stack_to_args(true, cs, 0);
        gen_call_novm(cs, helper, 2);
        if (stackFix != 0) {
            alu(alu_sub, sp, stackFix);
        }
        runlock(cs);
        gen_save_ret(cs);
        return;
    }
    assert(op == OPCODE_LCMP);
    char *helper = (char *)rt_h_lcmp;
    SYNC_FIRST(static const CallSig cs(CCONV_STDCALL, i32, i64, i64));
    unsigned stackFix = gen_stack_to_args(true, cs, 0);
    gen_call_novm(cs, helper, 2);
    if (stackFix != 0) {
        alu(alu_sub, sp, stackFix);
    }
    runlock(cs);
    gen_save_ret(cs);
}
コード例 #2
0
ファイル: thread_helpers_ia32.cpp プロジェクト: dacut/juliet
/**
  *  Generates monitor exit.
  *  The code should not contain safepoints.
  *
  *  @param[in] ss buffer to put the assembly code to
  *  @param[in] input_param1 register should point to the lockword in object header.
  *  If input_param1 == ecx it reduce one register mov.
  *  The code use and do not restore eax, ecx registers.
  *  @return 0 if success in eax register
  */
char* gen_monitor_exit_helper(char *ss, const R_Opnd & input_param1) {
    if (&input_param1 != &ecx_opnd) {
        ss = mov(ss, ecx_opnd,  input_param1);
    }
#ifdef ASM_MONITOR_HELPER
	ss = mov(ss,  eax_opnd, M_Base_Opnd(ecx_reg, 0));               //  mov eax,dword[ecx]
	ss = test(ss, eax_opnd, Imm_Opnd(0x80000000), size_32);         //  test eax,0x80000000
	ss = branch8(ss, Condition_NZ,  Imm_Opnd(size_8, 0));           //  jnz fat
	char *fat = ((char *)ss) - 1;
	ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, 1), size_8);        //  mov al, byte[ecx+1]

    ss = alu(ss, sub_opc,  eax_opnd, Imm_Opnd(size_8,0x8),size_8);  //  sub al, 0x8
	ss = branch8(ss, Condition_C,  Imm_Opnd(size_8, 0));            //  jc zero_rec
	char *zero_rec = ((char *)ss) - 1;
	ss = mov(ss,  M_Base_Opnd(ecx_reg, 1), eax_opnd, size_8);       //  mov byte[ecx+1],al
    ss = ret(ss,  Imm_Opnd(4));                                     //  ret 4

    signed offset = (signed)ss - (signed)zero_rec - 1;              //zero_rec:
    *zero_rec = (char)offset;

    ss = mov(ss, M_Base_Opnd(ecx_reg, 2), Imm_Opnd(size_16, 0), size_16);// mov word[ecx+2],0
	ss = ret(ss,  Imm_Opnd(4));                                     // ret 4

    offset = (signed)ss - (signed)fat - 1;                         //fat:
    *fat = (char)offset;

#endif

    ss = push(ss,  ecx_opnd);
    ss = call(ss, (char *)hythread_thin_monitor_exit);
    ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters
    return ss;
}
コード例 #3
0
char * m2n_gen_pop_m2n(char * buf, bool handles, unsigned num_callee_saves,
                      I_32 bytes_to_m2n_bottom, unsigned num_preserve_ret) {
    assert (num_preserve_ret <= 2);
    assert(LcgEM64TContext::GR_SIZE == 8);

    if (num_preserve_ret > 0) {
        // Save return value
        // NOTE: don't break stack allignment by pushing only one register.
        buf = push(buf,  rax_opnd, size_64);
        buf = push(buf,  rdx_opnd, size_64);
    }

    if (handles) {
        // There are handles located on the stack
        buf = mov(buf, rax_opnd, Imm_Opnd(size_64, (uint64)m2n_pop_local_handles), size_64);
    } else {
        buf = mov(buf, rax_opnd, Imm_Opnd(size_64, (uint64)m2n_free_local_handles), size_64);
    }
    
    // NOTE: the following should be true before the call ($rsp % 8 == 0 && $rsp % 16 != 0)!

    // Call m2n_pop_local_handles or m2n_free_local_handles
#ifdef _WIN64
    buf = alu(buf, add_opc, rsp_opnd, Imm_Opnd(-SHADOW));
#endif
    buf = call(buf, rax_opnd, size_64);
#ifdef _WIN64
    buf = alu(buf, add_opc, rsp_opnd, Imm_Opnd(SHADOW));
#endif
    
    if (num_preserve_ret > 0) {
        // Restore return value
        buf = pop(buf,  rdx_opnd, size_64);
        buf = pop(buf,  rax_opnd, size_64);
    }

    // pop prev_m2nf
    buf = mov(buf, r10_opnd, M_Base_Opnd(rsp_reg, bytes_to_m2n_bottom), size_64);
    bytes_to_m2n_bottom += LcgEM64TContext::GR_SIZE;
    // pop p_lm2nf
    buf = mov(buf, r11_opnd, M_Base_Opnd(rsp_reg, bytes_to_m2n_bottom), size_64);
    bytes_to_m2n_bottom += LcgEM64TContext::GR_SIZE;
    buf = mov(buf, M_Base_Opnd(r11_reg, 0), r10_opnd, size_64);
    // skip local_object_handles, method, current_frame_type, pop_regs
    bytes_to_m2n_bottom += 4 * LcgEM64TContext::GR_SIZE;

    // restore part of callee-saves registers
    for (int i = LcgEM64TContext::MAX_GR_LOCALS - 1; i >= (int)num_callee_saves; i--) {
        buf = mov(buf,
            LcgEM64TContext::get_reg_from_map(LcgEM64TContext::GR_LOCALS_OFFSET + i),
            M_Base_Opnd(rsp_reg, bytes_to_m2n_bottom),
            size_64);
        bytes_to_m2n_bottom += LcgEM64TContext::GR_SIZE;
    }

    return buf;
}//m2n_gen_pop_m2n
コード例 #4
0
ファイル: alu-main.c プロジェクト: InvertedBit/6502_emu
/*
  take string cmd_line, parse the line and call the alu function
  corresponding to alu-opcodes.h
*/
void alu_parse_line(char *cmd_line){
  char opcode[100];
  char operand1[100];
  char operand2[100];
  int nargs = 0;
  
  nargs = sscanf (cmd_line, "%s %s %s", opcode, operand1, operand2);
  
  switch(nargs){
  case 3:
    ldhex2register(operand1, rega);
    ldhex2register(operand2, regb);
    if(!strcmp(opcode,"add")){
      alu(ALU_OP_ADD, rega, regb, accumulator, flags);
    }
    if(!strcmp(opcode,"adc")){
      alu(ALU_OP_ADD_WITH_CARRY, rega, regb, accumulator, flags);
    }
    if(!strcmp(opcode,"sub"))
      alu(ALU_OP_SUB, rega, regb, accumulator, flags);
    if(!strcmp(opcode,"and"))
      alu(ALU_OP_AND, rega, regb, accumulator, flags);
    if(!strcmp(opcode,"or"))
      alu(ALU_OP_OR, rega, regb, accumulator, flags);
    if(!strcmp(opcode,"xor"))
      alu(ALU_OP_XOR, rega, regb, accumulator, flags);
    printf("%s %s %s\n", opcode, operand1, operand2);
    break;
  case 2:
    if(!strcmp(opcode,"neg_a")){
      ldhex2register(operand1, rega);
      alu(ALU_OP_NEG_A, rega, regb, accumulator, flags);
    }
    if(!strcmp(opcode,"neg_b")){
      ldhex2register(operand1, regb);
      alu(ALU_OP_NEG_B, rega, regb, accumulator, flags);
    }
    if(!strcmp(opcode,"not_a")){
      ldhex2register(operand1, rega);
      alu(ALU_OP_NOT_A, rega, regb, accumulator, flags);
    }
    if(!strcmp(opcode,"not_b")){
      ldhex2register(operand1, regb);
      alu(ALU_OP_NOT_B, rega, regb, accumulator, flags);
    }
    printf("%s %s\n", opcode, operand1);
    break;
  case 1:
    if(!strcmp(opcode,"reset")){
      alu_main_reset(rega, regb, accumulator, flags);
      printf("%s\n", opcode);
      break;
    }
    break;
  }
}
コード例 #5
0
/**
 * Provides fine-tuned implementation for IDIV/IREM operations on IA32-compatible platforms, 
 * in replacement of common arithmetic helper (see arith_rt.h).
 */
bool CodeGen::gen_a_platf(JavaByteCodes op, jtype jt)
{
    if (jt != i32) return false;
    if (op != OPCODE_IDIV && op != OPCODE_IREM) {
        return false;
    }
    //
    // The method is supposed to be platform-depended, and may not have 
    // Encoder support - leaving as-is, without implementing general 
    // support in Encoder
    //
    
    vpark(eax.reg());
    vpark(edx.reg());
    rlock(eax);
    rlock(edx);
    Val& v1 = vstack(1, vis_imm(1));
    Val& v2 = vstack(0, true);
    alu(alu_cmp, v2.as_opnd(), Opnd(-1));
    unsigned br_normal = br(ne, 0, 0);
    alu(alu_cmp, v1.as_opnd(), Opnd(INT_MIN));
    unsigned br_exit = NOTHING;
    if (op == OPCODE_IREM) {
        do_mov(edx, Opnd(0)); // prepare exit value for the corner case
        br_exit = br(eq, 0, 0);
    }
    else {
        do_mov(eax, v1);
        br_exit = br(eq, 0, 0);
    }
    patch(br_normal, ip());
    do_mov(eax, v1);
    //
    // The method is supposed to be platform-depended, and may not have 
    // Encoder support - leaving as-is, without implementing general 
    // support in Encoder
    //
    
    //CDQ
    EncoderBase::Operands args0(RegName_EDX, RegName_EAX);
    ip(EncoderBase::encode(ip(), Mnemonic_CDQ, args0));
    //IDIV
    EncoderBase::Operands args(RegName_EDX, RegName_EAX, 
                               devirt(v2.reg(), i32));
    ip(EncoderBase::encode(ip(), Mnemonic_IDIV, args));
    patch(br_exit, ip());

    vpop();
    vpop();
    vpush(op == OPCODE_IREM ? edx : eax);
    runlock(eax);
    runlock(edx);
    return true;
}
コード例 #6
0
// inputs should be preserved outside if required since we do a call
// num_std_need_to_save registers will be preserved
char * m2n_gen_push_m2n(char * buf, Method_Handle method, 
                        frame_type current_frame_type, 
                        bool handles,
                        unsigned num_callee_saves,
                        unsigned num_std_need_to_save,
                        I_32 bytes_to_m2n_top) {
    // skip callee-saves registers
    bytes_to_m2n_top -= num_callee_saves * LcgEM64TContext::GR_SIZE;
    // TODO: check if it makes sense to save all callee-saves registers here
    //store rest of callee-saves registers
    for (unsigned i = num_callee_saves; i < LcgEM64TContext::MAX_GR_LOCALS; i++) {
        bytes_to_m2n_top -= LcgEM64TContext::GR_SIZE;
        buf = mov(buf,
            M_Base_Opnd(rsp_reg, bytes_to_m2n_top),
            LcgEM64TContext::get_reg_from_map(LcgEM64TContext::GR_LOCALS_OFFSET + i),
            size_64);        
    }
    // init pop_regs to null
    bytes_to_m2n_top -= LcgEM64TContext::GR_SIZE;
    buf = mov(buf, M_Base_Opnd(rsp_reg, bytes_to_m2n_top),
        Imm_Opnd(size_32, 0), size_64);
    // store current_frame_type
    bytes_to_m2n_top -= LcgEM64TContext::GR_SIZE;
    assert(fit32(current_frame_type));
    buf = mov(buf, M_Base_Opnd(rsp_reg, bytes_to_m2n_top),
        Imm_Opnd(size_32, current_frame_type), size_64);
    // store a method associated with the current m2n frame
    bytes_to_m2n_top -= LcgEM64TContext::GR_SIZE;
    if (fit32((int64)method)) {
        buf = mov(buf, M_Base_Opnd(rsp_reg, bytes_to_m2n_top),
            Imm_Opnd(size_32, (int64)method), size_64);
    } else {
        buf = mov(buf, rax_opnd, Imm_Opnd(size_64, (int64)method), size_64);
        buf = mov(buf, M_Base_Opnd(rsp_reg, bytes_to_m2n_top), rax_opnd);
    }
    // store local object handles
    bytes_to_m2n_top -= LcgEM64TContext::GR_SIZE;
    buf = mov(buf, M_Base_Opnd(rsp_reg, bytes_to_m2n_top),
        Imm_Opnd(size_64, (int64)0), size_64);

    // move pointer to the current VM_Thread structure to rax
    buf = m2n_gen_ts_to_register(buf, &rax_opnd,
        num_callee_saves, LcgEM64TContext::MAX_GR_LOCALS,
        num_std_need_to_save, 0);
    
    // shift to the last_m2n_frame field
    I_32 last_m2n_frame_offset = (I_32)(int64)&((VM_thread*)0)->last_m2n_frame;
    buf = alu(buf, add_opc,  rax_opnd,  Imm_Opnd(size_32, last_m2n_frame_offset), size_64);
    // store pointer to pointer to last m2n frame
    bytes_to_m2n_top -= LcgEM64TContext::GR_SIZE;
    buf = mov(buf, M_Base_Opnd(rsp_reg, bytes_to_m2n_top), rax_opnd, size_64);
    // save pointer to the previous m2n frame
    bytes_to_m2n_top -= LcgEM64TContext::GR_SIZE;
    buf = mov(buf, r9_opnd, M_Base_Opnd(rax_reg, 0));
    buf = mov(buf, M_Base_Opnd(rsp_reg, bytes_to_m2n_top), r9_opnd, size_64);
    // update last m2n frame of the current thread
    buf = lea(buf, r9_opnd, M_Base_Opnd(rsp_reg, bytes_to_m2n_top));
    buf = mov(buf,  M_Base_Opnd(rax_reg, 0), r9_opnd, size_64);
    return buf;
}
コード例 #7
0
static void* getaddress__pop_java_to_native_frame()
{
    static void *addr = 0;
    if (addr) {
        return addr;
    }

    const int stub_size = 32 + m2n_pop_m2n_size(false, 1, 0);
    char *stub = (char *)malloc_fixed_code_for_jit(stub_size, DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_MAX/2, CAA_Allocate);
#ifdef _DEBUG
    memset(stub, 0xcc /*int 3*/, stub_size);
#endif
    char *ss = stub;

    ss = mov(ss, r12_opnd, rax_opnd);

    ss = m2n_gen_pop_m2n(ss, false, 1, 8, 0);

    ss = mov(ss, rax_opnd, r12_opnd);
    ss = mov(ss, r11_opnd, M_Base_Opnd(rsp_reg, 0));
    ss = mov(ss, r12_opnd, M_Base_Opnd(rsp_reg, m2n_sizeof_m2n_frame - 8));
    ss = mov(ss, M_Base_Opnd(rsp_reg, m2n_sizeof_m2n_frame - 8), r11_opnd);
    ss = alu(ss, add_opc, rsp_opnd, Imm_Opnd(m2n_sizeof_m2n_frame - 8));
    ss = ret(ss);

    assert((ss - stub) <= stub_size);
    addr = stub;

    compile_add_dynamic_generated_code_chunk("pop_java_to_native_frame", false, stub, stub_size);

    // Put TI support here.
    DUMP_STUB(stub, "getaddress__pop_java_to_native_frame", ss - stub);

    return addr;
} //getaddress__pop_java_to_native_frame
コード例 #8
0
ファイル: thread_helpers_ia32.cpp プロジェクト: dacut/juliet
/**
  *  Generates slow path of monitor exit.
  *  This code could block on monitor and contains safepoint.
  *  The appropriate m2n frame should be generated and
  *
  *  @param[in] ss buffer to put the assembly code to
  *  @param[in] input_param1 register should point to the jobject(handle)
  *  If input_param1 == eax it reduces one register mov.
  *  the code use and do not restore ecx, edx, eax registers
  *  @return 0 if success in eax register
  */
char* gen_monitorexit_slow_path_helper(char *ss, const R_Opnd & input_param1) {
    if (&input_param1 != &eax_opnd) {
        ss = mov(ss, eax_opnd,  input_param1);
    }

    ss = push(ss, eax_opnd); // push the address of the handle
    ss = call(ss, (char *)jthread_monitor_exit);
    ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters
    return ss;
}
コード例 #9
0
void Compiler::gen_if(JavaByteCodes opcod, unsigned target)
{
    if (target <= m_pc) {
        // have back branch here
        gen_prof_be();
        gen_gc_safe_point();
    }
    jtype jt = i32;
    if (opcod == OPCODE_IFNULL) {
        opcod = OPCODE_IFEQ;
        jt = jobj;
    }
    else if (opcod == OPCODE_IFNONNULL) {
        opcod = OPCODE_IFNE;
        jt = jobj;
    }
    OpndKind kind = m_jframe->dip(0).kind();
    bool forceReg = (kind == opnd_imm) || (jt == jobj && g_refs_squeeze);
    Opnd op1 = vstack(0, forceReg).as_opnd();
    vpop();
    rlock(op1);
    COND cond = to_cond(opcod);
    static const Opnd zero((int)0);
    if (jt == jobj && g_refs_squeeze) {
        AR ar = valloc(jobj);
        movp(ar, NULL_REF);
        alu(alu_cmp, Opnd(jobj, ar), op1);
    }
    else if (opcod == OPCODE_IFEQ || opcod == OPCODE_IFNE) {
        if (op1.is_reg()) {
            alu(alu_test, op1, op1);
        }
        else {
            alu(alu_cmp, op1, zero);
        }
    }
    else {
        alu(alu_cmp, op1, zero);
    }
    runlock(op1);
    gen_bb_leave(target);
    br(cond, target, m_bbinfo->start);
}
コード例 #10
0
void Compiler::gen_if_icmp(JavaByteCodes opcod, unsigned target)
{
    if (target <= m_pc) {
        // have back branch here
        gen_prof_be();
        gen_gc_safe_point();
    }
    if (opcod == OPCODE_IF_ACMPEQ) {
        opcod = OPCODE_IF_ICMPEQ;
    }
    else if (opcod == OPCODE_IF_ACMPNE) {
        opcod = OPCODE_IF_ICMPNE;
    }
    Opnd op2 = vstack(0).as_opnd();
    vpop();
    rlock(op2);
    OpndKind kind = m_jframe->dip(0).kind();
    // 'Bad' combinations are 'm,m' and 'imm,<any, but imm>' - have to force
    // an item into a register
    bool forceReg = (op2.is_mem() && kind == opnd_mem) || 
                    (op2.is_imm() && kind == opnd_imm);
    Opnd op1 = vstack(0, forceReg).as_opnd();
    vpop();
    rlock(op1);
    
    COND cond = to_cond(opcod);
    if ( (op1.is_mem() && op2.is_reg()) || op1.is_imm()) {
        // here we have 'mem, reg' or 'imm, mem-or-reg' - swap them so it
        // become 'reg, mem' (more efficient) or 'mem-or-reg, imm' (existent)
        // operations. change the branch condition appropriately.
        alu(alu_cmp, op2, op1);
        cond = flip(cond);
    }
    else {
        alu(alu_cmp, op1, op2);
    }
    
    runlock(op1);
    runlock(op2);
    gen_bb_leave(target);
    br(cond, target, m_bbinfo->start);
}
コード例 #11
0
ファイル: thumb.cpp プロジェクト: Cydrak/dasShiny
void ARMCore::thumbDataLo(uint4 opcode, uint3 ird, uint3 irm) {
  auto &rd = r[ird], rm = r[irm];
  r[15] += 2;
  
       if(opcode ==  2) { SOut r = lsl(rd, rm); bitf(true, rd = r, r); }  // lsls
  else if(opcode ==  3) { SOut r = lsr(rd, rm); bitf(true, rd = r, r); }  // lsrs
  else if(opcode ==  4) { SOut r = asr(rd, rm); bitf(true, rd = r, r); }  // asrs
  else if(opcode ==  7) { SOut r = ror(rd, rm); bitf(true, rd = r, r); }  // rors
  else if(opcode ==  9) sumf(true, rd = -rm, 0, ~rm);                     // negs
  else if(opcode == 13) bitf(true, rd = rm * rd, {rm*rd, Cf});            // muls
  else alu(2*opcode+1, rd, rd, {rm,Cf});                // others are same as ARM
}
コード例 #12
0
static void* getaddress__setup_java_to_native_frame()
{
    static void *addr = 0;
    if (addr) {
        return addr;
    }

    const int stub_size = 32 + m2n_push_m2n_size(1, 0);
    char *stub = (char *)malloc_fixed_code_for_jit(stub_size, DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_MAX/2, CAA_Allocate);

#ifdef _DEBUG
    memset(stub, 0xcc /*int 3*/, stub_size);
#endif
    char *ss = stub;

    // Stack changes
    //    prev        new
    //
    //    ...         ...
    //  --------    --------   ------------
    //    ret         ret
    //  --------    --------
    //    ret         r12
    //  --------    --------    m2n frame
    //
    //                ...
    //
    //              --------   ------------
    //                ret
    //              --------

    ss = alu(ss, sub_opc, rsp_opnd, Imm_Opnd(m2n_sizeof_m2n_frame - 8));
    ss = mov(ss, r11_opnd, M_Base_Opnd(rsp_reg, m2n_sizeof_m2n_frame - 8));
    ss = mov(ss, M_Base_Opnd(rsp_reg, m2n_sizeof_m2n_frame - 8), r12_opnd);
    ss = mov(ss, M_Base_Opnd(rsp_reg, 0), r11_opnd);
    ss = mov(ss, r12_opnd, rdi_opnd);

    ss = m2n_gen_push_m2n(ss, NULL, FRAME_UNKNOWN, false, 1, 0,
            m2n_sizeof_m2n_frame);
    ss = mov(ss,  rdi_opnd, r12_opnd);
    ss = ret(ss);

    assert((ss - stub) <= stub_size);
    addr = stub;

    compile_add_dynamic_generated_code_chunk("setup_java_to_native_frame", false, stub, stub_size);

    // Put TI support here.
    DUMP_STUB(stub, "getaddress__setup_java_to_native_frame", ss - stub);

    return addr;
} //getaddress__setup_java_to_native_frame
コード例 #13
0
void CodeGen::gen_cnv(jtype from, jtype to)
{
    if (from<i32 && to==i32) {
        // no op
        return;
    }
    char *helper = (char *) cnv_matrix_impls[from][to];
    const CallSig cs(CCONV_STDCALL, to, from);
    unsigned stackFix = gen_stack_to_args(true, cs, 0);
    gen_call_novm(cs, helper, 1);
    if (stackFix != 0) {
        alu(alu_sub, sp, stackFix);
    }
    runlock(cs);
    gen_save_ret(cs);
}
コード例 #14
0
ファイル: sim.c プロジェクト: nicolaslarsen/AndersNicolas
int interp_ex() {
    ex_mem.mem_read       = id_ex.mem_read;
    ex_mem.mem_write      = id_ex.mem_write;
    ex_mem.reg_write      = id_ex.reg_write;
    ex_mem.branch         = id_ex.branch;
    ex_mem.beq            = id_ex.beq;
    ex_mem.rt             = id_ex.rt;
    ex_mem.rt_value       = id_ex.rt_value;
    ex_mem.mem_to_reg     = id_ex.mem_to_reg;
    ex_mem.reg_dst        = id_ex.reg_dst;
    ex_mem.branch_target  = id_ex.next_pc + (id_ex.sign_ext_imm << 2);

    int retAlu = alu();

    if (retAlu != SAW_SYSCALL && retAlu != 0) {
        printf("ERROR: alu() failed\n");
    }

    return retAlu;
}
コード例 #15
0
ファイル: main.cpp プロジェクト: taweesoft/com-sys-lab5
int sc_main(int argc, char* argv[])
{

  sc_trace_file *ar = sc_create_vcd_trace_file("Wave");
  sc_trace(ar, ain, "ain");
	sc_trace(ar, bin, "bin");
	sc_trace(ar, sum, "sum");
  sc_trace(ar, operation,"operation");
  sc_trace(ar, owf , "owf-flag");
  sc_trace(ar, zero , "zero-flag");
  sc_trace(ar, lessFlag, "less-than-flag");

  ain.write("0b0000000000001000");
  bin.write("0b0000000000000111");
  alu alu("alu");
  alu.ain(ain);
  alu.bin(bin);
  alu.sum(sum);
  alu.owf(owf);
  alu.zero(zero);
  alu.less(lessFlag);
  alu.operation(operation);

  /*Write dummy value*/
  operation.write(10);
  sc_start(100,SC_NS);

  /*Start ALU 6 times*/
  for(int i =0;i<7;i++){
    operation.write(i);
    sc_start(100,SC_NS);
    print(); //print the result
  }

  sc_close_vcd_trace_file(ar);
}
コード例 #16
0
bool CodeGen::gen_a_generic(JavaByteCodes op, jtype jt)
{
    if (op == OPCODE_INEG) {
        return false; // later
    }
    if (jt == i32) {
        bool v2_imm = vis_imm(0);
        if (v2_imm &&
            (op == OPCODE_ISHL || op == OPCODE_ISHL || op == OPCODE_IUSHR)) {
            // accept it
        }
        /*else if (v2_imm && (op == OPCODE_IMUL || op == OPCODE_IDIV)) {
            // accept it
        }
        else if (op == OPCODE_IMUL) {
            // accept it
        }*/
        else if (op == OPCODE_IADD || op == OPCODE_ISUB) {
            // accept it
        }
        else if (op == OPCODE_IOR || op == OPCODE_IAND || op == OPCODE_IXOR) {
            // accept it
        }
        else if (vis_imm(0) && m_jframe->size()>1 && vis_imm(1)) {
            // accept it
        }
        else {
            return false;
        }
    }
    else if (is_f(jt)) {
        if (op != OPCODE_IADD && op != OPCODE_ISUB && 
            op != OPCODE_IMUL && op != OPCODE_IDIV) {
            return false;    
        }
    }
    else {
        return false;
    }
    
    bool is_dbl = jt == dbl64;
    unsigned v1_depth = is_dbl?2:1;
    
    if (vis_imm(v1_depth) && vis_imm(0)) {
        const Val& v1 = m_jframe->dip(v1_depth);
        const Val& v2 = m_jframe->dip(0);
        Val res;
        if (jt==dbl64) {
            double d = rt_h_dbl_a(v1.dval(), v2.dval(), op);
            res = Val(d);
        }
        else if (jt==flt32) {
            float f = rt_h_flt_a(v1.fval(), v2.fval(), op);
            res = Val(f);
        }
        else {
            assert(jt==i32);
            int i = rt_h_i32_a(v1.ival(), v2.ival(), op);
            res = Val(i);
        }
        vpop();
        vpop();
        vpush(res);
        return true;
    } // if v1.is_imm() && v2.is_imm()
    

    const Val& v1 = vstack(v1_depth, true);
    Opnd res = v1.as_opnd();
    if (rrefs(v1.reg()) > 1) {
        rlock(v1);
        AR ar = valloc(jt);
        runlock(v1);
        Opnd reg(jt, ar);
        mov(reg, v1.as_opnd());
        res = reg;
    }
    rlock(res);
    rlock(v1);
    const Val& v2 = m_jframe->dip(0);
/*    if (false )v2.
        
#ifdef _IA32_
        // on IA32 can use address in a displacement
        alu(to_alu(op), v1, ar_x, (int)v2.addr());
#else
        AR addr = valloc(jobj); rlock(addr);
        movp(addr, v2.addr());
        alu_mem(jt, to_alu(op), r1, addr);
        runlock(addr);
#endif
    }
    else */
    if(v2.is_mem()) {
        // Everyone can do 'reg, mem' operation
        alu(to_alu(op), res, v2.as_opnd());
    }
    else if(v2.is_imm() && jt==i32) {
        // 'reg, imm' is only for i32 operations
        alu(to_alu(op), res, v2.ival());
    }
    else {
        Opnd v2 = vstack(0, true).as_opnd();
        alu(to_alu(op), res, v2);
    }
    vpop();
    vpop();
    runlock(v1);
    runlock(res);
    vpush(res);

    return true;
}
コード例 #17
0
static transfer_control_stub_type gen_transfer_control_stub()
{
    static transfer_control_stub_type addr = NULL;

    if (addr) {
        return addr;
    }

    const int STUB_SIZE = 255;
    char * stub = (char *)malloc_fixed_code_for_jit(STUB_SIZE,
        DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_COLD, CAA_Allocate);
    char * ss = stub;
#ifndef NDEBUG
    memset(stub, 0xcc /*int 3*/, STUB_SIZE);
#endif

    //
    // ************* LOW LEVEL DEPENDENCY! ***************
    // This code sequence must be atomic.  The "atomicity" effect is achieved by
    // changing the rsp at the very end of the sequence.

    // rdx holds the pointer to the stack iterator
#if defined (PLATFORM_POSIX) // RDI holds 1st parameter on Linux
    ss = mov(ss, rdx_opnd, rdi_opnd);
#else // RCX holds 1st parameter on Windows
    ss = mov(ss, rdx_opnd, rcx_opnd);
#endif

    // Restore general registers
    ss = get_reg(ss, rbp_opnd, rdx_reg, CONTEXT_OFFSET(p_rbp), false);
    ss = get_reg(ss, rbx_opnd, rdx_reg, CONTEXT_OFFSET(p_rbx), true);
    ss = get_reg(ss, r12_opnd, rdx_reg, CONTEXT_OFFSET(p_r12), true);
    ss = get_reg(ss, r13_opnd, rdx_reg, CONTEXT_OFFSET(p_r13), true);
    ss = get_reg(ss, r14_opnd, rdx_reg, CONTEXT_OFFSET(p_r14), true);
    ss = get_reg(ss, r15_opnd, rdx_reg, CONTEXT_OFFSET(p_r15), true);
    ss = get_reg(ss, rsi_opnd, rdx_reg, CONTEXT_OFFSET(p_rsi), true);
    ss = get_reg(ss, rdi_opnd, rdx_reg, CONTEXT_OFFSET(p_rdi), true);
    ss = get_reg(ss, r8_opnd,  rdx_reg, CONTEXT_OFFSET(p_r8),  true);
    ss = get_reg(ss, r9_opnd,  rdx_reg, CONTEXT_OFFSET(p_r9),  true);
    ss = get_reg(ss, r10_opnd, rdx_reg, CONTEXT_OFFSET(p_r10), true);
    ss = get_reg(ss, r11_opnd, rdx_reg, CONTEXT_OFFSET(p_r11), true);

    // Get the new RSP
    M_Base_Opnd saved_rsp(rdx_reg, CONTEXT_OFFSET(rsp));
    ss = mov(ss, rax_opnd, saved_rsp);
    // Store it over return address for future use
    ss = mov(ss, M_Base_Opnd(rsp_reg, 0), rax_opnd);
    // Get the new RIP
    ss = get_reg(ss, rcx_opnd, rdx_reg, CONTEXT_OFFSET(p_rip), false);
    // Store RIP to [<new RSP> - 136] to preserve 128 bytes under RSP
    // which are 'reserved' on Linux
    ss = mov(ss,  M_Base_Opnd(rax_reg, -136), rcx_opnd);

    ss = get_reg(ss, rax_opnd, rdx_reg, CONTEXT_OFFSET(p_rax), true);

    // Restore processor flags
    ss = movzx(ss, rcx_opnd,  M_Base_Opnd(rdx_reg, CONTEXT_OFFSET(eflags)), size_16);
    ss = test(ss, rcx_opnd, rcx_opnd);
    ss = branch8(ss, Condition_Z,  Imm_Opnd(size_8, 0));
    char* patch_offset = ((char*)ss) - 1; // Store location for jump patch
    *ss++ = (char)0x9C; // PUSHFQ
    M_Base_Opnd sflags(rsp_reg, 0);
    ss = alu(ss, and_opc, sflags, Imm_Opnd(size_32,FLG_CLEAR_MASK), size_32);
    ss = alu(ss, and_opc, rcx_opnd, Imm_Opnd(size_32,FLG_SET_MASK), size_32);
    ss = alu(ss, or_opc, sflags, rcx_opnd, size_32);
    *ss++ = (char)0x9D; // POPFQ
    // Patch conditional jump
    POINTER_SIZE_SINT offset =
        (POINTER_SIZE_SINT)ss - (POINTER_SIZE_SINT)patch_offset - 1;
    *patch_offset = (char)offset;

    ss = get_reg(ss, rcx_opnd, rdx_reg, CONTEXT_OFFSET(p_rcx), true, true);
    ss = get_reg(ss, rdx_opnd, rdx_reg, CONTEXT_OFFSET(p_rdx), true, true);

    // Setup stack pointer to previously saved value
    ss = mov(ss,  rsp_opnd,  M_Base_Opnd(rsp_reg, 0));

    // Jump to address stored to [<new RSP> - 136]
    ss = jump(ss,  M_Base_Opnd(rsp_reg, -136));

    addr = (transfer_control_stub_type)stub;
    assert(ss-stub <= STUB_SIZE);

    /*
       The following code will be generated:

        mov         rdx,rcx
        mov         rbp,qword ptr [rdx+10h]
        mov         rbp,qword ptr [rbp]
        mov         rbx,qword ptr [rdx+20h]
        test        rbx,rbx
        je          __label1__
        mov         rbx,qword ptr [rbx]
__label1__
        ; .... The same for r12,r13,r14,r15,rsi,rdi,r8,r9,r10
        mov         r11,qword ptr [rdx+88h]
        test        r11,r11
        je          __label11__
        mov         r11,qword ptr [r11]
__label11__
        mov         rax,qword ptr [rdx+8]
        mov         qword ptr [rsp],rax
        mov         rcx,qword ptr [rdx+18h]
        mov         rcx,qword ptr [rcx]
        mov         qword ptr [rax-88h],rcx
        mov         rax,qword ptr [rdx+48h]
        test        rax,rax
        je          __label12__
        mov         rax,qword ptr [rax]
__label12__
        movzx       rcx,word ptr [rdx+90h]
        test        rcx,rcx
        je          __label13__
        pushfq
        and         dword ptr [rsp], 0x003F7202
        and         ecx, 0x00000CD5
        or          dword ptr [esp], ecx
        popfq
__label13__
        mov         rcx,qword ptr [rdx+50h]
        pushfq
        test        rcx,rcx
        je          __label14__
        mov         rcx,qword ptr [rcx]
__label14__
        popfq
        mov         rdx,qword ptr [rdx+58h]
        pushfq
        test        rdx,rdx
        je          __label15__
        mov         rdx,qword ptr [rdx]
__label15__
        popfq
        mov         rsp,qword ptr [rsp]
        jmp         qword ptr [rsp-88h]
    */

    DUMP_STUB(stub, "getaddress__transfer_control", ss-stub);

    return addr;
}
コード例 #18
0
ファイル: alu.c プロジェクト: ahirOrg/ahir
unsigned short start()
{
  return alu(3);
}
コード例 #19
0
ファイル: controller.cpp プロジェクト: kjwitt/MicroSimulator
void execute(char instruction, char data) {	
	char dataBus = 0;
	switch ((unsigned char) instruction) {
		case LDAD: 
			ACC = dataMemory->access(0, data);
			break;

		case LDAI:
			ACC = data;
			break;

		case STA :
			dataMemory->access(1, data, ACC);
			break;

		case ADDD:
			dataBus = dataMemory->access(0, data);
			ACC = alu(SR, 0, ACC, dataBus, 0, 2, 0);
			break;

		case ADDI:
			ACC = alu(SR, 0, ACC, data, 0, 2, 0);
			break;

		case ADCD:
			dataBus = dataMemory->access(0, data);
			ACC = alu(SR, 0, ACC, dataBus, 0, 0, 0);
			break;

		case ADCI:
			ACC = alu(SR, 0, ACC, data, 0, 0, 0);
			break;

		case SUBD:
			dataBus = dataMemory->access(0, data);
			ACC = alu(SR, 0, ACC, dataBus, 1, 2, 0);
			break;

		case SUBI:
			ACC = alu(SR, 0, ACC, data, 1, 2, 0);
			break;

		case SBCD:
			dataBus = dataMemory->access(0, data);
			ACC = alu(SR, 0, ACC, dataBus, 1, 0, 0);
			break;

		case SBCI:
			ACC = alu(SR, 0, ACC, data, 1, 0, 0);
			break;

		case INC :
			ACC = alu(SR, 0, ACC, '1', 0, 2, 0);
			break;

		case DEC :
			ACC = alu(SR, 0, ACC, '1', 1, 2, 0);
			break;

		case ANDD:
			dataBus = dataMemory->access(0, data);
			ACC = alu(SR, 1, ACC, dataBus, 0, 0, 0);
			break;

		case ANDI:
			ACC = alu(SR, 1, ACC, data, 0, 0, 0);
			break;

		case ORD :
			dataBus = dataMemory->access(0, data);
			ACC = alu(SR, 1, ACC, dataBus, 0, 0, 1);
			break;

		case ORI :
			ACC = alu(SR, 1, ACC, data, 0, 0, 1);
			break;

		case INV :
			ACC = alu(SR, 1, ACC, data, 0, 0, 2);
			break;

		case XORD:
			dataBus = dataMemory->access(0, data);
			ACC = alu(SR, 1, ACC, dataBus, 0, 0, 3);
			break;

		case XORI:
			ACC = alu(SR, 1, ACC, data, 0, 0, 3);
			break;

		case CLRA:
			ACC = '0';
			break;

		case CLRC:
			SR.setc(0);
			break;

		case CSET:
			SR.setc(1);
			break;

		case CMPD: 
			dataBus = dataMemory->access(0, data);
			alu(SR, 0, ACC, dataBus, 1, 2, 0);
			break;

		case CMPI:
			alu(SR, 0, ACC, data, 1, 2, 0);
			break;

		default:
			char destinationQuestionMark; 
			//JUMP(instruction, &destinationQuestionMark, SR, &programCounter);
			break;
		}
}
コード例 #20
0
ファイル: thread_helpers_ia32.cpp プロジェクト: dacut/juliet
/**
  *  Generates fast path of monitor enter
  *  the code should not contains safepoint.
  *
  *  @param[in] ss buffer to put the assembly code to
  *  @param[in] input_param1 register which should point to the object lockword.
  *  If input_param1 == ecx it reduces one register mov.
  *  the code use and do not restore ecx, edx, eax registers
  *
  *  @return 0 if success in eax register
  */
char* gen_monitorenter_fast_path_helper(char *ss, const R_Opnd & input_param1) {

    if (&input_param1 != &ecx_opnd) {
        ss = mov(ss, ecx_opnd,  input_param1);
    }
#ifdef ASM_MONITOR_HELPER

    //get self_id
    ss = gen_hythread_self_helper(ss);
    ss = mov(ss,  edx_opnd,  M_Base_Opnd(eax_reg,
            hythread_get_thread_id_offset()));                          // mov edx,dword [eax+off]

    ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, 2), size_16);           // mov ax,word[ecx+2]
	ss = alu(ss, cmp_opc,  edx_opnd,  eax_opnd, size_16);           	// cmp dx,ax
    ss = branch8(ss, Condition_NZ,  Imm_Opnd(size_8, 0));               // jnz check_zero
    char *check_zero = ((char *)ss) - 1;
												                        //; ax==dx it's safe to do inc
	ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, 1), size_8);            // mov al, byte[ecx+1]
	                                                                    //rec_inc:

    ss = alu(ss, add_opc,  eax_opnd,  Imm_Opnd(size_8, 0x8), size_8);   // add al,0x8
    ss = branch8(ss, Condition_C,  Imm_Opnd(size_8, 0));                // jc failed
    char *failed1 = ((char *)ss) - 1;

	ss = mov(ss,  M_Base_Opnd(ecx_reg, 1), eax_opnd, size_8);           // mov byte[ecx+1],al
    ss = ret(ss,  Imm_Opnd(4));                                         // ret 4

    signed offset = (signed)ss - (signed)check_zero - 1;
    *check_zero = (char)offset;                                        //check_zero:

    ss = test(ss,  eax_opnd,  eax_opnd, size_16);                      //  test ax,ax
    ss = branch8(ss, Condition_NZ,  Imm_Opnd(size_8, 0));              //  jnz failed
    char *failed2 = ((char *)ss) - 1;

    ss = prefix(ss, lock_prefix);                                      //; here ax==0.
    ss = cmpxchg(ss,  M_Base_Opnd(ecx_reg, 2),  edx_opnd, size_16);    //  lock cmpxchg16 [ecx+2],dx
    ss = branch8(ss, Condition_NZ,  Imm_Opnd(size_8, 0));              //  jnz failed
    char *failed3 = ((char *)ss) - 1;


#ifdef LOCK_RESERVATION
	ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, 1), size_8);            //  mov al, byte[ecx+1]
    ss = test(ss,  eax_opnd,  Imm_Opnd(size_8, 0x4), size_8);           //  test al,0x4
    ss = branch8(ss, Condition_NZ,  Imm_Opnd(size_8, 0));               //  jnz finish
    char *finish = ((char *)ss) - 1;

    ss = alu(ss, add_opc,  eax_opnd,  Imm_Opnd(size_8, 0x8), size_8);   // add al,0x8
	ss = mov(ss,  M_Base_Opnd(ecx_reg, 1), eax_opnd, size_8);           // mov byte[ecx+1],al

    offset = (signed)ss - (signed)finish - 1;
    *finish = (char)offset;                            		            //finish:

#endif
    ss = ret(ss,  Imm_Opnd(4));                                         // ret 4

    offset = (signed)ss - (signed)failed1 - 1;
    *failed1 = (char)offset;                                 	        //failed:

    offset = (signed)ss - (signed)failed2 - 1;
    *failed2 = (char)offset;

    offset = (signed)ss - (signed)failed3 - 1;
    *failed3 = (char)offset;

#endif //ASM_MONITOR_HELPER
    // the second attempt to lock monitor
    ss = push(ss,  ecx_opnd);
    ss = call(ss, (char *)hythread_thin_monitor_try_enter);
    ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters

    return ss;
}
コード例 #21
0
void Compiler::gen_switch(const JInst & jinst)
{
    assert(jinst.opcode == OPCODE_LOOKUPSWITCH 
           || jinst.opcode == OPCODE_TABLESWITCH);
    Opnd val = vstack(0, true).as_opnd();
    vpop();
    rlock(val);
    gen_bb_leave(NOTHING);

    if (jinst.opcode == OPCODE_LOOKUPSWITCH) {
        unsigned n = jinst.get_num_targets();
        for (unsigned i = 0; i < n; i++) {
            Opnd key(jinst.key(i));
            unsigned pc = jinst.get_target(i);
            alu(alu_cmp, val, key);
            br(eq, pc, m_bbinfo->start);
        }
        runlock(val);
        br(cond_none, jinst.get_def_target(), m_bbinfo->start);
        return;
    }
    //
    // TABLESWITCH
    //
    alu(alu_cmp, val, jinst.high());
    br(gt, jinst.get_def_target(), m_bbinfo->start);
    
    alu(alu_cmp, val, jinst.low());
    br(lt, jinst.get_def_target(), m_bbinfo->start);
    
    AR gr_tabl = valloc(jobj);
    movp(gr_tabl, DATA_SWITCH_TABLE | m_curr_inst->pc, m_bbinfo->start);
#ifdef _EM64T_
    // On EM64T, we operate with I_32 value in a register, but the 
    // register will be used as 64 bit in address form - have to extend
    sx(Opnd(i64, val.reg()), Opnd(i32, val.reg()));
#endif
    // Here, we need to extract 'index-=low()' - can pack this into 
    // complex address form:
    //      [table + index*sizeof(void*) - low()*sizeof(void*)],
    // but only if low()*sizeof(void*) does fit into displacement ...
    int tmp = -jinst.low();
    const int LO_BOUND = INT_MIN/(int)sizeof(void*);
    const int UP_BOUND = INT_MAX/(int)sizeof(void*);
    if (LO_BOUND<=tmp && tmp<=UP_BOUND) {
        ld(jobj, gr_tabl, gr_tabl, -jinst.low()*sizeof(void*), 
        val.reg(), sizeof(void*));
    }
    else {
        // ... otherwise subtract explicitly, but only if the register
        // is not used anywhere else
        if (rrefs(val.reg()) !=0) {
            Opnd vtmp(i32, valloc(i32));
            mov(vtmp, val); // make a copy of val
            runlock(val);
            val = vtmp;
            rlock(val);
        }
        alu(alu_sub, val, jinst.low());
        ld(jobj, gr_tabl, gr_tabl, 0, val.reg(), sizeof(void*));
    }
    runlock(val);
    br(gr_tabl);
}
コード例 #22
0
int
sc_main(int argc, char* argv[])
{
	sc_report_handler::
	set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING);

	char stbuf[256];

	// SIGNALS

	// Data signals
	sc_signal< sc_bv<DWORD> >		bus_mux1;
	sc_signal< sc_bv<DWORD> >		bus_mux2;
	sc_signal< sc_bv<DWORD> >		bus_mux3;
	sc_signal< sc_bv<AWORDREG> >		bus_mux4;

	sc_signal< sc_bv<6> >			bus_decoder_instr_31_26;
	sc_signal< sc_bv<AWORDREG> >		bus_decoder_instr_25_21;
	sc_signal< sc_bv<AWORDREG> >		bus_decoder_instr_20_16;
	sc_signal< sc_bv<AWORDREG> >		bus_decoder_instr_15_11;
	sc_signal< sc_bv<SIGNEXTENDBIT> >	bus_decoder_instr_15_0;
	sc_signal< sc_bv<6> >			bus_decoder_instr_5_0;

	sc_signal< sc_bv<DWORD> >		bus_pc;

	sc_signal< sc_bv<DWORD> >		bus_add1;
	sc_signal< sc_bv<DWORD> >		bus_add2;

	sc_signal< sc_bv<DWORD> >		bus_shiftleft;

	sc_signal< sc_bv<DWORD> >		bus_signextend;

	sc_signal< sc_bv<DWORD> >		bus_imem_1;

	sc_signal< sc_bv<DWORD> >		bus_dmem_1;

	sc_signal< sc_bv<DWORD> >		bus_alu_result;
	sc_signal< sc_bv<1> >			bus_alu_zero;

	sc_signal< sc_bv<DWORD> >		bus_registers_1;
	sc_signal< sc_bv<DWORD> >		bus_registers_2;

	// Control signals
	sc_signal< sc_bv<1> >		bus_ctrl_regdst;
	sc_signal< sc_bv<1> >		bus_ctrl_branch;
	sc_signal< sc_bv<1> >		bus_ctrl_memread;
	sc_signal< sc_bv<1> >		bus_ctrl_memtoreg;
	sc_signal< sc_bv<2> >		bus_ctrl_aluop;
	sc_signal< sc_bv<1> >		bus_ctrl_memwrite;
	sc_signal< sc_bv<1> >		bus_ctrl_alusrc;
	sc_signal< sc_bv<1> >		bus_ctrl_regwrite;
	sc_signal< sc_bv<DWORD> >	bus_ctrl_c4;

	sc_signal< sc_bv<3> >		bus_aluctrl;

	sc_signal< sc_bv<1> >		bus_and1;

	// MODULES

	REGISTER	pc("pc");
                            
	ADD		add1("add1");
	ADD		add2("add2");

	AND		and1("and1");

	ROM		imem("instruction_memory");	// Instruction memory
	RAM		dmem("data_memory");		// Data memory

	REGFILE		registers("registers");		// Registerfile

	ALU		alu("alu");
	ALUCTRL		aluctrl("aluctrl");

	SIGNEXTEND	signextend("signextend");

	SHIFTLEFT	shiftleft("shiftleft");

	CTRL		ctrl("ctrl");

	DECODER		decoder("decoder");

	MUX		mux1("mux1");
	MUX		mux2("mux2");
	MUX		mux3("mux3");
	MUX2_AWORDREG	mux4("mux4");

	sc_clock	clk("clock", 20);		// Clock

	// CONNECTIONS

	// Program counter
	pc.in(bus_mux1);
	pc.out(bus_pc);
	pc.w(clk);
	pc.clk(clk);

	// Add 1 (PC + 4)
	add1.a(bus_pc);
	add1.b(bus_ctrl_c4);
	add1.r(bus_add1);

	// Add 2 (add1 + shiftleft)
	add2.a(bus_add1);
	add2.b(bus_shiftleft);
	add2.r(bus_add2);

	// Mux 1 (add1 or add2)
	mux1.in0(bus_add1);
	mux1.in1(bus_add2);
	mux1.sel(bus_and1);
	mux1.out(bus_mux1);

	// Shift left 2
	shiftleft.in(bus_signextend);
	shiftleft.out(bus_shiftleft);

	// Sign extend
	signextend.in(bus_decoder_instr_15_0);
	signextend.out(bus_signextend);

	// Decoder (Select correct part of instruction for registerfile)
	decoder.instr(bus_imem_1);
	decoder.instr_31_26(bus_decoder_instr_31_26);
	decoder.instr_25_21(bus_decoder_instr_25_21);
	decoder.instr_20_16(bus_decoder_instr_20_16);
	decoder.instr_15_11(bus_decoder_instr_15_11);
	decoder.instr_15_0(bus_decoder_instr_15_0);
	decoder.instr_5_0(bus_decoder_instr_5_0);

	// Mux 4 (Select address for write to registerfile)
	mux4.in0(bus_decoder_instr_20_16);
	mux4.in1(bus_decoder_instr_15_11);
	mux4.sel(bus_ctrl_regdst);
	mux4.out(bus_mux4);

	// ALU
	alu.a(bus_registers_1);
	alu.b(bus_mux2);
	alu.r(bus_alu_result);
	alu.z(bus_alu_zero);
	alu.ctrl(bus_aluctrl);

	// Mux 2 (Registerfile or signextend)
	mux2.in0(bus_registers_2);
	mux2.in1(bus_signextend);
	mux2.sel(bus_ctrl_alusrc);
	mux2.out(bus_mux2);

	// ALU ctrl
	aluctrl.ALUop(bus_ctrl_aluop);
	aluctrl.functionCode(bus_decoder_instr_5_0);
	aluctrl.ALUctrl(bus_aluctrl);

	// Mux 3 (ALU result or memory result to register)
	mux3.in0(bus_alu_result);
	mux3.in1(bus_dmem_1);
	mux3.sel(bus_ctrl_memtoreg);
	mux3.out(bus_mux3);

	// AND
	and1.a(bus_alu_zero);
	and1.b(bus_ctrl_branch);
	and1.r(bus_and1);

	// Registerfile
	registers.r_addr_reg1(bus_decoder_instr_25_21);
	registers.r_addr_reg2(bus_decoder_instr_20_16);
	registers.w_addr_reg(bus_mux4);
	registers.r_data_reg1(bus_registers_1);
	registers.r_data_reg2(bus_registers_2);
	registers.w_data_reg(bus_mux3);
	registers.w(bus_ctrl_regwrite);
	registers.clk(clk);

	// Data memory
	dmem.a_read(bus_alu_result);
	dmem.d_read(bus_dmem_1);
	dmem.r(bus_ctrl_memread);
	dmem.a_write(bus_alu_result);
	dmem.d_write(bus_registers_2);
	dmem.w(bus_ctrl_memwrite);
	dmem.clk(clk);

	// Instruction Memory 
	imem.a_read(bus_pc);
	imem.d_read(bus_imem_1);
	imem.clk(clk);

	// Controller
	ctrl.Opcode(bus_decoder_instr_31_26);
	ctrl.RegDst(bus_ctrl_regdst);
	ctrl.Branch(bus_ctrl_branch);
	ctrl.MemRead(bus_ctrl_memread);
	ctrl.MemtoReg(bus_ctrl_memtoreg);
	ctrl.ALUop(bus_ctrl_aluop);
	ctrl.MemWrite(bus_ctrl_memwrite);
	ctrl.ALUSrc(bus_ctrl_alusrc);
	ctrl.RegWrite(bus_ctrl_regwrite);
	ctrl.c4(bus_ctrl_c4);

	// INITIALIZATION

	imem.rom_init("mips.rom"); 
	dmem.ram_init("mips.ram");

	// TRACING

	sc_trace_file* tf;
	tf = sc_create_vcd_trace_file("mips");

	// Signals
	sc_trace(tf, clk,		"clock");
	sc_trace(tf, bus_mux1,			"bus_mux1");
	sc_trace(tf, bus_mux2,			"bus_mux2");
	sc_trace(tf, bus_mux3,			"bus_mux3");
	sc_trace(tf, bus_mux4,			"bus_mux4");
	sc_trace(tf, bus_pc,			"bus_pc");
	sc_trace(tf, bus_add1,			"bus_add1");
	sc_trace(tf, bus_add2,			"bus_add2");
	sc_trace(tf, bus_shiftleft,		"bus_shiftleft");
	sc_trace(tf, bus_signextend,		"bus_signextend");
	sc_trace(tf, bus_imem_1,		"bus_imem_1");
	sc_trace(tf, bus_dmem_1,		"bus_dmem_1");
	sc_trace(tf, bus_alu_result,		"bus_alu_result");
	sc_trace(tf, bus_alu_zero,		"bus_alu_zero");
	sc_trace(tf, bus_registers_1,		"bus_registers_1");
	sc_trace(tf, bus_registers_2,		"bus_registers_2");
	sc_trace(tf, bus_ctrl_regdst,		"bus_ctrl_regdst");
	sc_trace(tf, bus_ctrl_branch,		"bus_ctrl_branch");
	sc_trace(tf, bus_ctrl_memread,		"bus_ctrl_memread");
	sc_trace(tf, bus_ctrl_memtoreg,		"bus_ctrl_memtoreg");
	sc_trace(tf, bus_ctrl_aluop,		"bus_ctrl_aluop");
	sc_trace(tf, bus_ctrl_memwrite,		"bus_ctrl_memwrite");
	sc_trace(tf, bus_ctrl_alusrc,		"bus_ctrl_alusrc");
	sc_trace(tf, bus_ctrl_regwrite,		"bus_ctrl_regwrite");
	sc_trace(tf, bus_ctrl_c4,		"bus_ctrl_c4");
	sc_trace(tf, bus_aluctrl,		"bus_aluctrl");
	sc_trace(tf, bus_and1,			"bus_and1");
	sc_trace(tf, bus_decoder_instr_31_26,	"bus_decoder_instr_31_26");
	sc_trace(tf, bus_decoder_instr_25_21,	"bus_decoder_instr_25_21");
	sc_trace(tf, bus_decoder_instr_20_16,	"bus_decoder_instr_20_16");
	sc_trace(tf, bus_decoder_instr_15_11,	"bus_decoder_instr_15_11");
	sc_trace(tf, bus_decoder_instr_15_0,	"bus_decoder_instr_15_0");
	sc_trace(tf, bus_decoder_instr_5_0,	"bus_decoder_instr_5_0");

	for (int i = 0; i < REGSIZE; i++) {
		sprintf(stbuf, "registers.reg(%d)", i);
		sc_trace(tf, registers.rfile[i], stbuf);
	}

	for (int i = 0; i < RAMSIZE; i++) {
		sprintf(stbuf, "memory.dmem(%d)", i);
		sc_trace(tf, dmem.ramfile[i], stbuf);
	}

	for (int i = 0; i < ROMSIZE; i++) {
		sprintf(stbuf, "memory.imem(%d)", i);
		sc_trace(tf, imem.romfile[i], stbuf);
	}

	// SIMULATION

	int sim_time = 500;
	if (argc == 2)
		sim_time = atoi(argv[1]);

	sc_start(sim_time, SC_NS);

	sc_close_vcd_trace_file(tf);
	dmem.ram_dump("mips_ram.dump");

	return 0;
}
コード例 #23
0
ファイル: ctrl-uni.c プロジェクト: P3r4/iassim
void execute(uint64_t ir){    
    int op = decodeOp(ir);    
    alu(op,getReg(AC),getReg(MBR),getReg(MQ));
}
コード例 #24
0
// rsp should point to the bottom of the activation frame since push may occur
// inputs should be preserved outside if required since we do a call
// num_std_need_to_save registers will be preserved
char * m2n_gen_ts_to_register(char * buf, const R_Opnd * reg,
                              unsigned num_callee_saves_used,
                              unsigned num_callee_saves_max,
                              unsigned num_std_need_to_save,
                              unsigned num_ret_need_to_save) {
    // we can't preserve rax and return value on it at the same time
    assert (num_ret_need_to_save == 0 || reg != &rax_opnd);


//#ifdef PLATFORM_POSIX

    // preserve std places
    unsigned i;
    unsigned num_std_saved = 0;
    // use calle-saves registers first
        while (num_std_saved < num_std_need_to_save &&
        (i = num_callee_saves_used + num_std_saved) < num_callee_saves_max) {
            buf = mov(buf,
                LcgEM64TContext::get_reg_from_map(
                LcgEM64TContext::GR_LOCALS_OFFSET + i),
                LcgEM64TContext::get_reg_from_map(
                    LcgEM64TContext::STD_PLACES_OFFSET + num_std_saved),
                size_64);
            ++num_std_saved;
        }
    // if we still have not preserved std places save them on the stack
    while (num_std_saved < num_std_need_to_save) {
        buf = push(buf,
            LcgEM64TContext::get_reg_from_map(
                LcgEM64TContext::STD_PLACES_OFFSET + num_std_saved),
            size_64);
        ++num_std_saved;
    }
    assert(num_std_saved == num_std_need_to_save);

    // preserve returns
    unsigned num_ret_saved = 0;
        while (num_ret_saved < num_ret_need_to_save &&
        (i = num_callee_saves_used + num_std_saved + num_ret_saved) < num_callee_saves_max) {
            buf = mov(buf,
                LcgEM64TContext::get_reg_from_map(
                    LcgEM64TContext::GR_LOCALS_OFFSET + i),
                LcgEM64TContext::get_reg_from_map(
                    LcgEM64TContext::GR_RETURNS_OFFSET + num_ret_saved),
                    size_64);
                ++num_ret_saved;
            }
    // if we still have not preserved returns save them on the stack
    while (num_ret_saved < num_ret_need_to_save) {
        buf = push(buf,
            LcgEM64TContext::get_reg_from_map(
                LcgEM64TContext::GR_RETURNS_OFFSET + num_std_saved),
            size_64);
        ++num_ret_saved;
    }
    assert(num_ret_saved == num_ret_need_to_save);

    // TODO: FIXME: only absolute addressing mode is supported now
    buf = mov(buf, rax_opnd, Imm_Opnd(size_64, (uint64)get_thread_ptr), size_64);
#ifdef _WIN64
    buf = alu(buf, add_opc, rsp_opnd, Imm_Opnd(-SHADOW));
#endif
    buf = call(buf, rax_opnd, size_64);
#ifdef _WIN64
    buf = alu(buf, add_opc, rsp_opnd, Imm_Opnd(SHADOW));
#endif
    if (reg != &rax_opnd) {
        buf = mov(buf, *reg,  rax_opnd, size_64);
    }

    // restore returns from the stack
    i = num_callee_saves_used + num_std_saved;
    while (num_ret_saved > 0 && i + num_ret_saved > num_callee_saves_max) {
            --num_ret_saved;
        buf = pop(buf,
            LcgEM64TContext::get_reg_from_map(
                LcgEM64TContext::GR_RETURNS_OFFSET + num_ret_saved),
            size_64);
        }
    // restore std places from the stack
    while (num_std_saved > 0 && num_callee_saves_used + num_std_saved > num_callee_saves_max) {
            --num_std_saved;
        buf = pop(buf,
            LcgEM64TContext::get_reg_from_map(
                LcgEM64TContext::STD_PLACES_OFFSET + num_std_saved),
            size_64);
        }
    // restore returns from callee-saves registers
    i = num_callee_saves_used + num_std_saved;
        while (num_ret_saved > 0) {
            --num_ret_saved;
        buf = mov(buf,
            LcgEM64TContext::get_reg_from_map(
                LcgEM64TContext::GR_RETURNS_OFFSET + num_ret_saved),
                LcgEM64TContext::get_reg_from_map(
                LcgEM64TContext::GR_LOCALS_OFFSET + i + num_ret_saved),
                size_64);
        }
    // restore std places from callee-saves registers
        while (num_std_saved > 0) {
            --num_std_saved;
        buf = mov(buf,
            LcgEM64TContext::get_reg_from_map(
                LcgEM64TContext::STD_PLACES_OFFSET + num_std_saved),
                LcgEM64TContext::get_reg_from_map(
                LcgEM64TContext::GR_LOCALS_OFFSET + num_callee_saves_used + num_std_saved),
                size_64);
        }
//#else //!PLATFORM_POSIX
//    buf = prefix(buf, prefix_fs);
//    buf = mov(buf, *reg,  M_Opnd(0x14), size_64);
//#endif //!PLATFORM_POSIX
    return buf;
}
コード例 #25
0
ファイル: ini_iA32.cpp プロジェクト: dacut/juliet
static char* gen_invoke_common_managed_func(char* stub) {
    // Defines stack alignment on managed function enter.
    const I_32 STACK_ALIGNMENT = MANAGED_STACK_ALIGNMENT;
    const I_32 STACK_ALIGNMENT_MASK = ~(STACK_ALIGNMENT - 1);
    const char * LOOP_BEGIN = "loop_begin";
    const char * LOOP_END = "loop_end";

    // [ebp + 8] - args
    // [ebp + 12] - size
    // [ebp + 16] - func
    const I_32 STACK_ARGS_OFFSET = 8;
    const I_32 STACK_NARGS_OFFSET = 12;
    const I_32 STACK_FUNC_OFFSET = 16;
    const I_32 STACK_CALLEE_SAVED_OFFSET = -12;

    tl::MemoryPool pool;
    LilCguLabelAddresses labels(&pool, stub);

    // Initialize ebp-based stack frame.
    stub = push(stub, ebp_opnd);
    stub = mov(stub, ebp_opnd, esp_opnd);

    // Preserve callee-saved registers.
    stub = push(stub, ebx_opnd);
    stub = push(stub, esi_opnd);
    stub = push(stub, edi_opnd);

    // Load an array of arguments ('args') and its size from the stack.
    stub = mov(stub, eax_opnd, M_Base_Opnd(ebp_reg, STACK_ARGS_OFFSET));
    stub = mov(stub, ecx_opnd, M_Base_Opnd(ebp_reg, STACK_NARGS_OFFSET));


    // Align memory stack.
    stub = lea(stub, ebx_opnd, M_Index_Opnd(n_reg, ecx_reg, 4, 4));
    stub = mov(stub, esi_opnd, ebx_opnd);
    stub = neg(stub, esi_opnd);
    stub = alu(stub, add_opc, esi_opnd, esp_opnd);
    stub = alu(stub, and_opc, esi_opnd, Imm_Opnd(size_32, STACK_ALIGNMENT_MASK));
    stub = alu(stub, add_opc, ebx_opnd, esi_opnd);
    stub = mov(stub, esp_opnd, ebx_opnd);

    // Load a pointer to the last argument of 'args' array.
    stub = lea(stub, eax_opnd, M_Index_Opnd(eax_reg, ecx_reg, -4, 4));
    stub = alu(stub, sub_opc, eax_opnd, esp_opnd);
    stub = alu(stub, or_opc, ecx_opnd, ecx_opnd);
    stub = branch8(stub, Condition_Z, Imm_Opnd(size_8, 0));
    labels.add_patch_to_label(LOOP_END, stub - 1, LPT_Rel8);

// LOOP_BEGIN:
    // Push inputs on the stack.
    labels.define_label(LOOP_BEGIN, stub, false);

    stub = push(stub, M_Index_Opnd(esp_reg, eax_reg, 0, 1));
    stub = loop(stub, Imm_Opnd(size_8, 0));
    labels.add_patch_to_label(LOOP_BEGIN, stub - 1, LPT_Rel8);

// LOOP_END:
    labels.define_label(LOOP_END, stub, false);

    // Call target function.
    stub = mov(stub, eax_opnd, M_Base_Opnd(ebp_reg, STACK_FUNC_OFFSET));
    stub = call(stub, eax_opnd);

    // Restore callee-saved registers from the stack.
    stub = lea(stub, esp_opnd, M_Base_Opnd(ebp_reg, STACK_CALLEE_SAVED_OFFSET));
    stub = pop(stub, edi_opnd);
    stub = pop(stub, esi_opnd);
    stub = pop(stub, ebx_opnd);

    // Leave current frame.
    stub = pop(stub, ebp_opnd);

    return stub;
}
コード例 #26
0
void CodeGen::gen_a(JavaByteCodes op, jtype jt)
{
    if (gen_a_platf(op, jt)) {
        return;
    }
    
    if (gen_a_generic(op, jt)) {
        return;
    }
    
    if (is_f(jt) && gen_a_f(op, jt)) {
        return;
    }
    
    if (jt == i32 && gen_a_i32(op)) {
        return;
    }

    unsigned stackFix = 0;
    bool shft = op == OPCODE_ISHL || op == OPCODE_ISHR || op == OPCODE_IUSHR;
    const CallSig* rcs = NULL;
    if (is_f(jt)) {
        assert(jt == dbl64 || jt == flt32);
        char * helper = NULL;
        bool is_dbl = jt == dbl64;
        if (op == OPCODE_INEG) {
            SYNC_FIRST(static const CallSig cs_dbl(CCONV_STDCALL, dbl64, dbl64));
            SYNC_FIRST(static const CallSig cs_flt(CCONV_STDCALL, flt32, flt32));
            rcs = is_dbl? &cs_dbl : &cs_flt;
            stackFix = gen_stack_to_args(true, *rcs, 0, 1);
            helper = is_dbl ? (char*)&rt_h_neg_dbl64 : (char*)&rt_h_neg_flt32;
            gen_call_novm(*rcs, helper, 1);
            runlock(*rcs);
        }
        else {
            //if (m_jframe->dip(1).stype == st_imm && )
            SYNC_FIRST(static const CallSig cs_dbl(CCONV_STDCALL, dbl64, dbl64, dbl64, i32));
            SYNC_FIRST(static const CallSig cs_flt(CCONV_STDCALL, flt32, flt32, flt32, i32));
            rcs = is_dbl? &cs_dbl : &cs_flt;
            stackFix = gen_stack_to_args(true, *rcs, 0, 2);
            helper = is_dbl ? (char*)&rt_h_dbl_a : (char*)&rt_h_flt_a;
            gen_call_novm(*rcs, helper, 2, op);
            runlock(*rcs);
        }
    }
    else if (jt==i64) {
        if (op == OPCODE_INEG) {
            SYNC_FIRST(static const CallSig cs(CCONV_STDCALL, i64, i64));
            rcs = &cs;
            stackFix = gen_stack_to_args(true, *rcs, 0, 1);
            gen_call_novm(*rcs, (void*)&rt_h_neg_i64, 1);
            runlock(*rcs);
        }
        else if (shft) {
            SYNC_FIRST(static const CallSig cs(CCONV_STDCALL, i64, i64, i32, i32));
            rcs = &cs;
            stackFix = gen_stack_to_args(true, *rcs, 0, 2);
            gen_call_novm(*rcs, (void*)&rt_h_i64_shift, 2, op);
            runlock(*rcs);
        }
        else {
            SYNC_FIRST(static const CallSig cs(CCONV_STDCALL, i64, i64, i64, i32));
            rcs = &cs;
            stackFix = gen_stack_to_args(true, *rcs, 0, 2);
            gen_call_novm(*rcs, (void*)&rt_h_i64_a, 2, op);
            runlock(*rcs);
        }
    }
    else {
        assert(jt==i32);
        if (op == OPCODE_INEG) {
            SYNC_FIRST(static const CallSig cs(CCONV_STDCALL, i32, i32));
            rcs = &cs;
            stackFix = gen_stack_to_args(true, *rcs, 0, 1);
            gen_call_novm(*rcs, (void*)&rt_h_neg_i32, 1);
            runlock(*rcs);
        }
        else if (op == OPCODE_IADD || op == OPCODE_ISUB) {
            const Val& op2 = vstack(0);
            vpop();
            rlock(op2);
            const Val& op1 = vstack(0);
            vpop();
            rlock(op1);
            AR ar = valloc(i32);
            Opnd reg(i32, ar);
            //TODO: may eliminate additional register allocation
            mov(reg, op1.as_opnd());
            alu(op == OPCODE_IADD ? alu_add : alu_sub, reg, op2.as_opnd());
            runlock(op1);
            runlock(op2);
            vpush(Val(i32, ar));
            return;
        }
        else {
            SYNC_FIRST(static const CallSig cs(CCONV_STDCALL, i32, i32, i32, i32));
            rcs = &cs;
            stackFix = gen_stack_to_args(true, *rcs, 0, 2);
            gen_call_novm(*rcs, (void*)&rt_h_i32_a, 2, op);
            runlock(*rcs);
        }
    }
    assert(rcs != NULL);
    gen_save_ret(*rcs);
    if (stackFix != 0) {
        alu(alu_sub, sp, stackFix);
    }
}