From acdaac31c648fd10f1bd0a49c4c33b483bb9c35c Mon Sep 17 00:00:00 2001 From: Jerome Laheurte Date: Wed, 26 Nov 2014 13:29:08 +0100 Subject: [PATCH] Preserve NEON/VFP registers across subroutines according to ARM PCS (5.1.2.1) https://bugzilla.gnome.org/show_bug.cgi?id=727464 --- orc/orcarm.c | 94 ++++++++++++++++++++++++++++++++++++++------------- orc/orcarm.h | 4 +-- orc/orcprogram-arm.c | 6 ++-- orc/orcprogram-neon.c | 26 ++++++++++++-- 4 files changed, 98 insertions(+), 32 deletions(-) diff --git a/orc/orcarm.c b/orc/orcarm.c index e89066e..065fab4 100644 --- a/orc/orcarm.c +++ b/orc/orcarm.c @@ -79,45 +79,91 @@ orc_arm_emit_bx_lr (OrcCompiler *compiler) } void -orc_arm_emit_push (OrcCompiler *compiler, int regs) +orc_arm_emit_push (OrcCompiler *compiler, int regs, orc_uint32 vregs) { int i; - int x = 0; - - ORC_ASM_CODE(compiler," push {"); - for(i=0;i<16;i++){ - if (regs & (1<program->name); @@ -45,8 +46,15 @@ orc_neon_emit_prologue (OrcCompiler *compiler) regs |= (1<used_regs[ORC_VEC_REG_BASE+i] && + compiler->save_regs[ORC_VEC_REG_BASE+i]) { + vregs |= (1U << i); + } + } + + orc_arm_emit_push (compiler, regs, vregs); } void @@ -57,7 +65,7 @@ orc_neon_dump_insns (OrcCompiler *compiler) orc_arm_emit_add (compiler, ORC_ARM_A2, ORC_ARM_A3, ORC_ARM_A4); orc_arm_emit_sub (compiler, ORC_ARM_A2, ORC_ARM_A3, ORC_ARM_A4); - orc_arm_emit_push (compiler, 0x06); + orc_arm_emit_push (compiler, 0x06, 0U); orc_arm_emit_mov (compiler, ORC_ARM_A2, ORC_ARM_A3); orc_arm_emit_branch (compiler, ORC_ARM_COND_LE, 0); @@ -73,6 +81,7 @@ orc_neon_emit_epilogue (OrcCompiler *compiler) { int i; unsigned int regs = 0; + orc_uint32 vregs = 0; for(i=0;i<16;i++){ if (compiler->used_regs[ORC_GP_REG_BASE + i] && @@ -80,7 +89,15 @@ orc_neon_emit_epilogue (OrcCompiler *compiler) regs |= (1<used_regs[ORC_VEC_REG_BASE+i] && + compiler->save_regs[ORC_VEC_REG_BASE+i]) { + vregs |= (1U << i); + } + } + + orc_arm_emit_pop (compiler, regs, vregs); orc_arm_emit_bx_lr (compiler); /* arm_dump_insns (compiler); */ @@ -145,6 +162,9 @@ orc_compiler_neon_init (OrcCompiler *compiler) for(i=4;i<12;i++) { compiler->save_regs[ORC_GP_REG_BASE+i] = 1; } + for(i=8;i<16;i++) { + compiler->save_regs[ORC_VEC_REG_BASE+i] = 1; + } for(i=0;ialloc_regs[i] = 0; -- 2.7.4