From 8f247bf2fd675dc67991f4d01a7ff8058e9b822d Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sat, 1 Dec 2012 17:12:53 -0800 Subject: [PATCH] Adds support for PowerPC64 --- orc/orcpowerpc.c | 69 +++++++++++++++++++++++++++++++++++++++++++----- orc/orcpowerpc.h | 7 +++++ orc/orcprogram-altivec.c | 69 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 124 insertions(+), 21 deletions(-) diff --git a/orc/orcpowerpc.c b/orc/orcpowerpc.c index 1d9c6c8..abace31 100644 --- a/orc/orcpowerpc.c +++ b/orc/orcpowerpc.c @@ -150,6 +150,48 @@ powerpc_emit_stwu (OrcCompiler *compiler, int regs, int rega, int offset) } void +powerpc_emit_ld (OrcCompiler *compiler, int regd, int rega, int imm) +{ + unsigned int insn; + + ORC_ASM_CODE(compiler," ld %s, %d(%s)\n", + powerpc_get_regname(regd), + imm, powerpc_get_regname(rega)); + insn = (58<<26) | (powerpc_regnum (regd)<<21) | (powerpc_regnum (rega)<<16); + insn |= imm&0xffff; + + powerpc_emit (compiler, insn); +} + +void +powerpc_emit_std (OrcCompiler *compiler, int regs, int rega, int offset) +{ + unsigned int insn; + + ORC_ASM_CODE(compiler," std %s, %d(%s)\n", + powerpc_get_regname(regs), + offset, powerpc_get_regname(rega)); + insn = (62<<26) | (powerpc_regnum (regs)<<21) | (powerpc_regnum (rega)<<16); + insn |= offset&0xffff; + + powerpc_emit (compiler, insn); +} + +void +powerpc_emit_stdu (OrcCompiler *compiler, int regs, int rega, int offset) +{ + unsigned int insn; + + ORC_ASM_CODE(compiler," stdu %s, %d(%s)\n", + powerpc_get_regname(regs), + offset, powerpc_get_regname(rega)); + insn = (62<<26) | (powerpc_regnum (regs)<<21) | (powerpc_regnum (rega)<<16); + insn |= (offset&0xffff) | 1; + + powerpc_emit (compiler, insn); +} + +void powerpc_emit_srawi (OrcCompiler *compiler, int regd, int rega, int shift, int record) { @@ -381,6 +423,9 @@ orc_powerpc_flush_cache (OrcCode *code) int size = code->code_size; ptr = code->code; +#ifdef __powerpc64__ + *(unsigned char **) ptr = (unsigned char *) code->exec + 24; +#endif for (i=0;iis_64bit) { + powerpc_emit_ld (p, + greg, + POWERPC_R3, + (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[ORC_VAR_A2])); + powerpc_emit_ld (p, + greg, greg, + (int)ORC_STRUCT_OFFSET(OrcCode, exec)); + } else { + powerpc_emit_lwz (p, + greg, + POWERPC_R3, + (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[ORC_VAR_A2])); + powerpc_emit_lwz (p, + greg, greg, + (int)ORC_STRUCT_OFFSET(OrcCode, exec)); + } powerpc_add_fixup (p, 1, p->codeptr, label_data); { diff --git a/orc/orcpowerpc.h b/orc/orcpowerpc.h index 947a833..bb6a71e 100644 --- a/orc/orcpowerpc.h +++ b/orc/orcpowerpc.h @@ -6,6 +6,10 @@ ORC_BEGIN_DECLS +typedef enum { + ORC_TARGET_POWERPC_64BIT = (1<<0) +} OrcTargetPowerPCFlags; + #ifdef ORC_ENABLE_UNSTABLE_API enum { @@ -86,6 +90,9 @@ void powerpc_emit_addi (OrcCompiler *compiler, int regd, int rega, int imm); void powerpc_emit_lwz (OrcCompiler *compiler, int regd, int rega, int imm); void powerpc_emit_stw (OrcCompiler *compiler, int regs, int rega, int offset); void powerpc_emit_stwu (OrcCompiler *compiler, int regs, int rega, int offset); +void powerpc_emit_ld (OrcCompiler *compiler, int regd, int rega, int imm); +void powerpc_emit_std (OrcCompiler *compiler, int regs, int rega, int offset); +void powerpc_emit_stdu (OrcCompiler *compiler, int regs, int rega, int offset); void powerpc_emit_ret (OrcCompiler *compiler); void powerpc_emit_b (OrcCompiler *compiler, int label); diff --git a/orc/orcprogram-altivec.c b/orc/orcprogram-altivec.c index 3801b88..56fbc7d 100644 --- a/orc/orcprogram-altivec.c +++ b/orc/orcprogram-altivec.c @@ -26,7 +26,17 @@ powerpc_emit_prologue (OrcCompiler *compiler) ORC_ASM_CODE (compiler, ".global %s\n", compiler->program->name); ORC_ASM_CODE (compiler, "%s:\n", compiler->program->name); - powerpc_emit_stwu (compiler, POWERPC_R1, POWERPC_R1, -16); + if (compiler->is_64bit) { + ORC_ASM_CODE (compiler, " .quad .%s,.TOC.@tocbase,0\n", + compiler->program->name); + ORC_ASM_CODE (compiler, ".%s:\n", compiler->program->name); + powerpc_emit (compiler, 0); powerpc_emit (compiler, 0); + powerpc_emit (compiler, 0); powerpc_emit (compiler, 0); + powerpc_emit (compiler, 0); powerpc_emit (compiler, 0); + powerpc_emit_stdu (compiler, POWERPC_R1, POWERPC_R1, -16); + } else { + powerpc_emit_stwu (compiler, POWERPC_R1, POWERPC_R1, -16); + } for(i=POWERPC_R13;i<=POWERPC_R31;i++){ if (compiler->used_regs[i]) { @@ -82,7 +92,13 @@ orc_powerpc_init (void) unsigned int orc_compiler_powerpc_get_default_flags (void) { - return 0; + unsigned int flags = 0; + +#ifdef __powerpc64__ + flags |= ORC_TARGET_POWERPC_64BIT; +#endif + + return flags; } void @@ -90,6 +106,10 @@ orc_compiler_powerpc_init (OrcCompiler *compiler) { int i; + if (compiler->target_flags & ORC_TARGET_POWERPC_64BIT) { + compiler->is_64bit = TRUE; + } + for(i=0;i<32;i++){ compiler->valid_regs[POWERPC_R0+i] = 1; compiler->valid_regs[POWERPC_V0+i] = 1; @@ -127,10 +147,17 @@ powerpc_load_inner_constants (OrcCompiler *compiler) case ORC_VAR_TYPE_SRC: case ORC_VAR_TYPE_DEST: if (compiler->vars[i].ptr_register) { - powerpc_emit_lwz (compiler, - compiler->vars[i].ptr_register, - POWERPC_R3, - (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[i])); + 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"); @@ -319,10 +346,17 @@ orc_compiler_powerpc_assemble (OrcCompiler *compiler) 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_lwz (compiler, - compiler->vars[k].ptr_register, - POWERPC_R3, - (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[k])); + 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, @@ -331,10 +365,17 @@ orc_compiler_powerpc_assemble (OrcCompiler *compiler) compiler->vars[k].ptr_register, compiler->vars[k].ptr_register, POWERPC_R0); - powerpc_emit_stw (compiler, - compiler->vars[k].ptr_register, - POWERPC_R3, - (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[k])); + 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"); } -- 2.7.4