void orc_sse_set_mxcsr (OrcCompiler *compiler) { orc_x86_emit_cpuinsn_load_memoffset (compiler, ORC_X86_stmxcsr, 4, 0, (int)ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A4]), compiler->exec_reg, 0); orc_x86_emit_mov_memoffset_reg (compiler, 4, (int)ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A4]), compiler->exec_reg, compiler->gp_tmpreg); orc_x86_emit_mov_reg_memoffset (compiler, 4, compiler->gp_tmpreg, (int)ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_C1]), compiler->exec_reg); orc_x86_emit_cpuinsn_imm_reg (compiler, ORC_X86_or_imm32_rm, 4, 0x8040, compiler->gp_tmpreg); orc_x86_emit_mov_reg_memoffset (compiler, 4, compiler->gp_tmpreg, (int)ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A4]), compiler->exec_reg); orc_x86_emit_cpuinsn_load_memoffset (compiler, ORC_X86_ldmxcsr, 4, 0, (int)ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A4]), compiler->exec_reg, 0); }
void arm_add_strides (OrcCompiler *compiler) { int i; for(i=0;i<ORC_N_COMPILER_VARIABLES;i++){ if (compiler->vars[i].name == NULL) continue; switch (compiler->vars[i].vartype) { case ORC_VAR_TYPE_CONST: break; case ORC_VAR_TYPE_PARAM: break; case ORC_VAR_TYPE_SRC: case ORC_VAR_TYPE_DEST: orc_arm_emit_load_reg (compiler, ORC_ARM_A3, compiler->exec_reg, (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[i])); orc_arm_emit_load_reg (compiler, ORC_ARM_A2, compiler->exec_reg, (int)ORC_STRUCT_OFFSET(OrcExecutor, params[i])); orc_arm_emit_add (compiler, ORC_ARM_A3, ORC_ARM_A3, ORC_ARM_A2); orc_arm_emit_store_reg (compiler, ORC_ARM_A3, compiler->exec_reg, (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[i])); break; case ORC_VAR_TYPE_ACCUMULATOR: break; case ORC_VAR_TYPE_TEMP: break; default: ORC_COMPILER_ERROR(compiler,"bad vartype"); break; } } }
void powerpc_load_inner_constants (OrcCompiler *compiler) { int i; for(i=0;i<ORC_N_COMPILER_VARIABLES;i++){ if (compiler->vars[i].name == NULL) continue; switch (compiler->vars[i].vartype) { case ORC_VAR_TYPE_SRC: case ORC_VAR_TYPE_DEST: if (compiler->vars[i].ptr_register) { if (compiler->is_64bit) { powerpc_emit_ld (compiler, compiler->vars[i].ptr_register, POWERPC_R3, (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[i])); } else { powerpc_emit_lwz (compiler, compiler->vars[i].ptr_register, POWERPC_R3, (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[i])); } } else { /* FIXME */ ORC_ASM_CODE(compiler,"ERROR"); } break; default: break; } } }
void orc_x86_assemble_copy (OrcCompiler *compiler) { OrcInstruction *insn; int shift = 0; insn = compiler->program->insns + 0; if (strcmp (insn->opcode->name, "copyw") == 0) { shift = 1; } else if (strcmp (insn->opcode->name, "copyl") == 0) { shift = 2; } compiler->used_regs[X86_EDI] = TRUE; compiler->used_regs[X86_ESI] = TRUE; orc_x86_emit_prologue (compiler); orc_x86_emit_mov_memoffset_reg (compiler, 4, (int)ORC_STRUCT_OFFSET(OrcExecutor,arrays[insn->dest_args[0]]), compiler->exec_reg, X86_EDI); orc_x86_emit_mov_memoffset_reg (compiler, 4, (int)ORC_STRUCT_OFFSET(OrcExecutor,arrays[insn->src_args[0]]), compiler->exec_reg, X86_ESI); orc_x86_emit_mov_memoffset_reg (compiler, 4, (int)ORC_STRUCT_OFFSET(OrcExecutor,n), compiler->exec_reg, compiler->gp_tmpreg); orc_x86_emit_sar_imm_reg (compiler, 4, 2 - shift, compiler->gp_tmpreg); orc_x86_emit_rep_movs (compiler, 4); if (shift == 0) { orc_x86_emit_mov_memoffset_reg (compiler, 4, (int)ORC_STRUCT_OFFSET(OrcExecutor,n), compiler->exec_reg, compiler->gp_tmpreg); orc_x86_emit_and_imm_reg (compiler, 4, 3, compiler->gp_tmpreg); orc_x86_emit_rep_movs (compiler, 1); } if (shift == 1) { orc_x86_emit_mov_memoffset_reg (compiler, 4, (int)ORC_STRUCT_OFFSET(OrcExecutor,n), compiler->exec_reg, compiler->gp_tmpreg); orc_x86_emit_and_imm_reg (compiler, 4, 1, compiler->gp_tmpreg); orc_x86_emit_rep_movs (compiler, 2); } orc_x86_emit_epilogue (compiler); orc_x86_do_fixups (compiler); }
void orc_x86_emit_epilogue (OrcCompiler *compiler) { #if 0 orc_x86_emit_rdtsc(compiler); orc_x86_emit_mov_reg_memoffset (compiler, 4, X86_EAX, ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A4]), compiler->exec_reg); #endif if (compiler->is_64bit) { int i; for(i=15;i>=0;i--){ if (compiler->used_regs[ORC_GP_REG_BASE+i] && compiler->save_regs[ORC_GP_REG_BASE+i]) { orc_x86_emit_pop (compiler, 8, ORC_GP_REG_BASE+i); } } } else { if (compiler->used_regs[X86_EBX]) { orc_x86_emit_pop (compiler, 4, X86_EBX); } if (compiler->used_regs[X86_ESI]) { orc_x86_emit_pop (compiler, 4, X86_ESI); } if (compiler->used_regs[X86_EDI]) { orc_x86_emit_pop (compiler, 4, X86_EDI); } orc_x86_emit_pop (compiler, 4, X86_EBP); } orc_x86_emit_ret (compiler); }
void orc_sse_restore_mxcsr (OrcCompiler *compiler) { orc_x86_emit_cpuinsn_load_memoffset (compiler, ORC_X86_ldmxcsr, 4, 0, (int)ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A4]), compiler->exec_reg, 0); }
void orc_compiler_orc_arm_assemble (OrcCompiler *compiler) { int dest_var = ORC_VAR_D1; compiler->vars[dest_var].is_aligned = FALSE; orc_arm_emit_prologue (compiler); orc_arm_load_constants_outer (compiler); if (compiler->program->is_2d) { if (compiler->program->constant_m > 0) { orc_arm_emit_load_imm (compiler, ORC_ARM_A3, compiler->program->constant_m ); orc_arm_emit_store_reg (compiler, ORC_ARM_A3, compiler->exec_reg, (int)ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A2])); } else { orc_arm_emit_load_reg (compiler, ORC_ARM_A3, compiler->exec_reg, (int)ORC_STRUCT_OFFSET(OrcExecutor, params[ORC_VAR_A1])); orc_arm_emit_store_reg (compiler, ORC_ARM_A3, compiler->exec_reg, (int)ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A2])); } orc_arm_emit_label (compiler, 8); } orc_arm_emit_load_reg (compiler, ORC_ARM_IP, compiler->exec_reg, (int)ORC_STRUCT_OFFSET(OrcExecutor,n)); orc_arm_load_constants_inner (compiler); orc_arm_emit_label (compiler, 1); orc_arm_emit_cmp_i (compiler, ORC_ARM_COND_AL, ORC_ARM_IP, 0); orc_arm_emit_branch (compiler, ORC_ARM_COND_EQ, 3); orc_arm_emit_label (compiler, 2); orc_arm_emit_loop (compiler); orc_arm_emit_sub_i (compiler, ORC_ARM_COND_AL, 0, ORC_ARM_IP, ORC_ARM_IP, 1); orc_arm_emit_cmp_i (compiler, ORC_ARM_COND_AL, ORC_ARM_IP, 0); orc_arm_emit_branch (compiler, ORC_ARM_COND_NE, 2); orc_arm_emit_label (compiler, 3); if (compiler->program->is_2d) { arm_add_strides (compiler); orc_arm_emit_load_reg (compiler, ORC_ARM_A3, compiler->exec_reg, (int)ORC_STRUCT_OFFSET(OrcExecutor, params[ORC_VAR_A2])); orc_arm_emit_sub_imm (compiler, ORC_ARM_A3, ORC_ARM_A3, 1, TRUE); orc_arm_emit_store_reg (compiler, ORC_ARM_A3, compiler->exec_reg, (int)ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A2])); orc_arm_emit_branch (compiler, ORC_ARM_COND_NE, 8); } orc_arm_emit_epilogue (compiler); orc_arm_do_fixups (compiler); }
void orc_arm_load_constants_inner (OrcCompiler *compiler) { int i; for(i=0;i<ORC_N_COMPILER_VARIABLES;i++){ if (compiler->vars[i].name == NULL) continue; switch (compiler->vars[i].vartype) { case ORC_VAR_TYPE_CONST: case ORC_VAR_TYPE_PARAM: break; case ORC_VAR_TYPE_SRC: case ORC_VAR_TYPE_DEST: orc_arm_emit_load_reg (compiler, compiler->vars[i].ptr_register, compiler->exec_reg, ORC_STRUCT_OFFSET(OrcExecutor, arrays[i])); break; default: break; } } }
void orc_x86_emit_prologue (OrcCompiler *compiler) { orc_compiler_append_code(compiler,".global %s\n", compiler->program->name); orc_compiler_append_code(compiler,".p2align 4\n"); orc_compiler_append_code(compiler,"%s:\n", compiler->program->name); if (compiler->is_64bit) { int i; for(i=0;i<16;i++){ if (compiler->used_regs[ORC_GP_REG_BASE+i] && compiler->save_regs[ORC_GP_REG_BASE+i]) { orc_x86_emit_push (compiler, 8, ORC_GP_REG_BASE+i); } } } else { orc_x86_emit_push (compiler, 4, X86_EBP); if (compiler->use_frame_pointer) { orc_x86_emit_mov_reg_reg (compiler, 4, X86_ESP, X86_EBP); } orc_x86_emit_mov_memoffset_reg (compiler, 4, 8, X86_ESP, compiler->exec_reg); if (compiler->used_regs[X86_EDI]) { orc_x86_emit_push (compiler, 4, X86_EDI); } if (compiler->used_regs[X86_ESI]) { orc_x86_emit_push (compiler, 4, X86_ESI); } if (compiler->used_regs[X86_EBX]) { orc_x86_emit_push (compiler, 4, X86_EBX); } } #if 0 orc_x86_emit_rdtsc(compiler); orc_x86_emit_mov_reg_memoffset (compiler, 4, X86_EAX, ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A3]), compiler->exec_reg); #endif }
void orc_compiler_powerpc_assemble (OrcCompiler *compiler) { int j; int k; OrcInstruction *insn; OrcStaticOpcode *opcode; //OrcVariable *args[10]; OrcRule *rule; int label_outer_loop_start; int label_loop_start; int label_leave; int set_vscr = FALSE; label_outer_loop_start = orc_compiler_label_new (compiler); label_loop_start = orc_compiler_label_new (compiler); label_leave = orc_compiler_label_new (compiler); powerpc_emit_prologue (compiler); if (orc_program_has_float (compiler)) { int tmp = POWERPC_V0; set_vscr = TRUE; ORC_ASM_CODE(compiler," vspltish %s, %d\n", powerpc_get_regname(tmp), 1); powerpc_emit_VX(compiler, 0x1000034c, powerpc_regnum(tmp), 1, 0); powerpc_emit_VX_b(compiler, "mtvscr", 0x10000644, tmp); } if (compiler->program->is_2d) { powerpc_emit_lwz (compiler, POWERPC_R0, POWERPC_R3, (int)ORC_STRUCT_OFFSET(OrcExecutorAlt, m)); powerpc_emit_srawi (compiler, POWERPC_R0, POWERPC_R0, compiler->loop_shift, 1); powerpc_emit_beq (compiler, label_leave); powerpc_emit_stw (compiler, POWERPC_R0, POWERPC_R3, (int)ORC_STRUCT_OFFSET(OrcExecutorAlt, m_index)); } //powerpc_load_constants (compiler); powerpc_load_inner_constants (compiler); for(k=0;k<4;k++){ OrcVariable *var = &compiler->vars[ORC_VAR_A1 + k]; if (compiler->vars[ORC_VAR_A1 + k].name == NULL) continue; //powerpc_emit_VX_2(p, "vxor", 0x100004c4, reg, reg, reg); powerpc_emit_vxor (compiler, var->alloc, var->alloc, var->alloc); } powerpc_emit_label (compiler, label_outer_loop_start); powerpc_emit_lwz (compiler, POWERPC_R0, POWERPC_R3, (int)ORC_STRUCT_OFFSET(OrcExecutor, n)); powerpc_emit_srawi (compiler, POWERPC_R0, POWERPC_R0, compiler->loop_shift, 1); powerpc_emit_beq (compiler, label_leave); powerpc_emit (compiler, 0x7c0903a6); ORC_ASM_CODE (compiler, " mtctr %s\n", powerpc_get_regname(POWERPC_R0)); powerpc_emit_label (compiler, label_loop_start); for(j=0;j<compiler->n_insns;j++){ insn = compiler->insns + j; opcode = insn->opcode; compiler->insn_index = j; ORC_ASM_CODE(compiler,"# %d: %s\n", j, insn->opcode->name); #if 0 /* set up args */ for(k=0;k<opcode->n_src + opcode->n_dest;k++){ args[k] = compiler->vars + insn->args[k]; ORC_ASM_CODE(compiler," %d", args[k]->alloc); if (args[k]->is_chained) { ORC_ASM_CODE(compiler," (chained)"); } } ORC_ASM_CODE(compiler,"\n"); #endif for(k=0;k<ORC_STATIC_OPCODE_N_SRC;k++){ OrcVariable *var = compiler->vars + insn->src_args[k]; if (opcode->src_size[k] == 0) continue; switch (var->vartype) { case ORC_VAR_TYPE_SRC: case ORC_VAR_TYPE_DEST: //powerpc_emit_load_src (compiler, var); break; case ORC_VAR_TYPE_CONST: break; case ORC_VAR_TYPE_TEMP: break; default: break; } } compiler->min_temp_reg = ORC_VEC_REG_BASE; rule = insn->rule; if (rule) { rule->emit (compiler, rule->emit_user, insn); } else { ORC_ASM_CODE(compiler,"No rule for: %s\n", opcode->name); } for(k=0;k<ORC_STATIC_OPCODE_N_DEST;k++){ OrcVariable *var = compiler->vars + insn->dest_args[k]; if (opcode->dest_size[k] == 0) continue; switch (var->vartype) { case ORC_VAR_TYPE_DEST: //powerpc_emit_store_dest (compiler, var); break; case ORC_VAR_TYPE_TEMP: break; default: break; } } } for(k=0;k<ORC_N_COMPILER_VARIABLES;k++){ if (compiler->vars[k].name == NULL) continue; if (compiler->vars[k].vartype == ORC_VAR_TYPE_SRC || compiler->vars[k].vartype == ORC_VAR_TYPE_DEST) { if (compiler->vars[k].ptr_register) { powerpc_emit_addi (compiler, compiler->vars[k].ptr_register, compiler->vars[k].ptr_register, compiler->vars[k].size << compiler->loop_shift); } else { ORC_ASM_CODE(compiler,"ERROR\n"); } } } powerpc_emit_bne (compiler, label_loop_start); if (compiler->program->is_2d) { powerpc_emit_lwz (compiler, POWERPC_R0, POWERPC_R3, (int)ORC_STRUCT_OFFSET(OrcExecutorAlt, m_index)); powerpc_emit_addi_rec (compiler, POWERPC_R0, POWERPC_R0, -1); powerpc_emit_beq (compiler, label_leave); powerpc_emit_stw (compiler, POWERPC_R0, POWERPC_R3, (int)ORC_STRUCT_OFFSET(OrcExecutorAlt, m_index)); for(k=0;k<ORC_N_COMPILER_VARIABLES;k++){ if (compiler->vars[k].name == NULL) continue; if (compiler->vars[k].vartype == ORC_VAR_TYPE_SRC || compiler->vars[k].vartype == ORC_VAR_TYPE_DEST) { if (compiler->vars[k].ptr_register) { if (compiler->is_64bit) { powerpc_emit_ld (compiler, compiler->vars[k].ptr_register, POWERPC_R3, (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[k])); } else { powerpc_emit_lwz (compiler, compiler->vars[k].ptr_register, POWERPC_R3, (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[k])); } powerpc_emit_lwz (compiler, POWERPC_R0, POWERPC_R3, (int)ORC_STRUCT_OFFSET(OrcExecutorAlt, strides[k])); powerpc_emit_add (compiler, compiler->vars[k].ptr_register, compiler->vars[k].ptr_register, POWERPC_R0); if (compiler->is_64bit) { powerpc_emit_std (compiler, compiler->vars[k].ptr_register, POWERPC_R3, (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[k])); } else { powerpc_emit_stw (compiler, compiler->vars[k].ptr_register, POWERPC_R3, (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[k])); } } else { ORC_ASM_CODE(compiler,"ERROR\n"); } } } powerpc_emit_b (compiler, label_outer_loop_start); } powerpc_emit_label (compiler, label_leave); for(k=0;k<4;k++){ OrcVariable *var = &compiler->vars[ORC_VAR_A1 + k]; if (compiler->vars[ORC_VAR_A1 + k].name == NULL) continue; powerpc_emit_addi (compiler, POWERPC_R0, POWERPC_R3, (int)ORC_STRUCT_OFFSET(OrcExecutor, accumulators[k])); if (var->size == 2) { powerpc_emit_vxor (compiler, POWERPC_V0, POWERPC_V0, POWERPC_V0); powerpc_emit_vmrghh (compiler, var->alloc, POWERPC_V0, var->alloc); } ORC_ASM_CODE(compiler," lvsr %s, 0, %s\n", powerpc_get_regname (POWERPC_V0), powerpc_get_regname (POWERPC_R0)); powerpc_emit_X (compiler, 0x7c00004c, powerpc_regnum(POWERPC_V0), 0, powerpc_regnum(POWERPC_R0)); powerpc_emit_vperm (compiler, var->alloc, var->alloc, var->alloc, POWERPC_V0); ORC_ASM_CODE(compiler," stvewx %s, 0, %s\n", powerpc_get_regname (var->alloc), powerpc_get_regname (POWERPC_R0)); powerpc_emit_X (compiler, 0x7c00018e, powerpc_regnum(var->alloc), 0, powerpc_regnum(POWERPC_R0)); } if (set_vscr) { int tmp = POWERPC_V0; ORC_ASM_CODE(compiler," vspltisw %s, %d\n", powerpc_get_regname(tmp), 0); powerpc_emit_VX(compiler, 0x1000038c, powerpc_regnum(tmp), 0, 0); powerpc_emit_VX_b(compiler, "mtvscr", 0x10000644, tmp); } powerpc_emit_epilogue (compiler); powerpc_do_fixups (compiler); }
static void powerpc_rule_loadpX (OrcCompiler *compiler, void *user, OrcInstruction *insn) { OrcVariable *src = compiler->vars + insn->src_args[0]; OrcVariable *dest = compiler->vars + insn->dest_args[0]; int size = ORC_PTR_TO_INT(user); if (src->vartype == ORC_VAR_TYPE_PARAM) { int greg = compiler->gp_tmpreg; powerpc_emit_addi (compiler, greg, POWERPC_R3, (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->src_args[0]])); ORC_ASM_CODE(compiler," lvewx %s, 0, %s\n", powerpc_get_regname (dest->alloc), powerpc_get_regname (greg)); powerpc_emit_X (compiler, 0x7c00008e, powerpc_regnum(dest->alloc), 0, powerpc_regnum(greg)); ORC_ASM_CODE(compiler," lvsl %s, 0, %s\n", powerpc_get_regname (POWERPC_V0), powerpc_get_regname (greg)); powerpc_emit_X (compiler, 0x7c00000c, powerpc_regnum(POWERPC_V0), 0, powerpc_regnum(greg)); powerpc_emit_vperm (compiler, dest->alloc, dest->alloc, dest->alloc, POWERPC_V0); switch (size) { case 1: ORC_ASM_CODE(compiler," vspltb %s, %s, 3\n", powerpc_get_regname (dest->alloc), powerpc_get_regname (dest->alloc)); powerpc_emit_VX (compiler, 0x1000020c, powerpc_regnum(dest->alloc), 3, powerpc_regnum(dest->alloc)); break; case 2: ORC_ASM_CODE(compiler," vsplth %s, %s, 1\n", powerpc_get_regname (dest->alloc), powerpc_get_regname (dest->alloc)); powerpc_emit_VX (compiler, 0x1000024c, powerpc_regnum(dest->alloc), 1, powerpc_regnum(dest->alloc)); break; case 4: ORC_ASM_CODE(compiler," vspltw %s, %s, 0\n", powerpc_get_regname (dest->alloc), powerpc_get_regname (dest->alloc)); powerpc_emit_VX (compiler, 0x1000028c, powerpc_regnum(dest->alloc), 0, powerpc_regnum(dest->alloc)); break; } } else { int value = src->value.i; switch (size) { case 1: if (value < 16 && value >= -16) { ORC_ASM_CODE(compiler," vspltisb %s, %d\n", powerpc_get_regname(dest->alloc), value&0x1f); powerpc_emit_VX(compiler, 0x1000030c, powerpc_regnum(dest->alloc), value & 0x1f, 0); } else { value &= 0xff; value |= value << 8; value |= value << 16; powerpc_load_long_constant (compiler, dest->alloc, value, value, value, value); } break; case 2: if (value < 16 && value >= -16) { ORC_ASM_CODE(compiler," vspltish %s, %d\n", powerpc_get_regname(dest->alloc), value&0x1f); powerpc_emit_VX(compiler, 0x1000034c, powerpc_regnum(dest->alloc), value & 0x1f, 0); } else { value &= 0xffff; value |= value << 16; powerpc_load_long_constant (compiler, dest->alloc, value, value, value, value); } break; case 4: if (value < 16 && value >= -16) { ORC_ASM_CODE(compiler," vspltisw %s, %d\n", powerpc_get_regname(dest->alloc), value&0x1f); powerpc_emit_VX(compiler, 0x1000038c, powerpc_regnum(dest->alloc), value & 0x1f, 0); } else { powerpc_load_long_constant (compiler, dest->alloc, value, value, value, value); } break; } } }