diff options
author | Wim Taymans <wtaymans@redhat.com> | 2014-12-10 13:33:37 +0100 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2014-12-10 15:37:35 +0100 |
commit | 98f3b33241fcdfe8ede33685f6418d87343b5a44 (patch) | |
tree | 928f23cc150d95c5e02fabba37d77f4a4211880a | |
parent | bc0140faf9bccd15445f2d837b9ffd0fb479a94c (diff) |
neon: add support for all constants
Use mov and orr to construct all constants.
-rw-r--r-- | orc/orcrules-neon.c | 130 |
1 files changed, 63 insertions, 67 deletions
diff --git a/orc/orcrules-neon.c b/orc/orcrules-neon.c index cc47a11..69a94e2 100644 --- a/orc/orcrules-neon.c +++ b/orc/orcrules-neon.c @@ -1015,6 +1015,7 @@ neon_rule_storeX (OrcCompiler *compiler, void *user, OrcInstruction *insn) } +#if 0 static int orc_neon_get_const_shift (unsigned int value) { @@ -1026,6 +1027,7 @@ orc_neon_get_const_shift (unsigned int value) } return shift; } +#endif void orc_neon_emit_loadib (OrcCompiler *compiler, int reg, int value) @@ -1054,30 +1056,29 @@ void orc_neon_emit_loadiw (OrcCompiler *compiler, int reg, int value) { orc_uint32 code; - int shift; - int neg = FALSE; if (value == 0) { orc_neon_emit_binary_quad (compiler, "veor", 0xf3000110, reg, reg, reg); return; } - if (value < 0) { - neg = TRUE; - value = ~value; - } - shift = orc_neon_get_const_shift (value); - if ((value & (0xff<<shift)) == value) { - value >>= shift; - if (neg) { - ORC_ASM_CODE(compiler," vmvn.i16 %s, #%d\n", - orc_neon_reg_name_quad (reg), value); - code = 0xf2800830; - } else { - ORC_ASM_CODE(compiler," vmov.i16 %s, #%d\n", - orc_neon_reg_name_quad (reg), value); - code = 0xf2800810; - } + ORC_ASM_CODE(compiler," vmov.i16 %s, #0x%04x\n", + orc_neon_reg_name_quad (reg), value & 0xff); + code = 0xf2800810; + code |= (reg&0xf) << 12; + code |= ((reg>>4)&0x1) << 22; + code |= (value&0xf) << 0; + code |= (value&0x70) << 12; + code |= (value&0x80) << 17; + code |= 0x40; + orc_arm_emit (compiler, code); + + value >>= 8; + if (value) { + ORC_ASM_CODE(compiler," vorr.i16 %s, #0x%04x\n", + orc_neon_reg_name_quad (reg), (value & 0xff) << 8); + code = 0xf2800b10; + code |= (reg&0xf) << 12; code |= ((reg>>4)&0x1) << 22; code |= (value&0xf) << 0; @@ -1085,54 +1086,38 @@ orc_neon_emit_loadiw (OrcCompiler *compiler, int reg, int value) code |= (value&0x80) << 17; code |= 0x40; orc_arm_emit (compiler, code); - - if (shift > 0) { - ORC_ASM_CODE(compiler," vshl.i16 %s, %s, #%d\n", - orc_neon_reg_name_quad (reg), orc_neon_reg_name_quad (reg), shift); - code = 0xf2900510; - code |= (reg&0xf) << 12; - code |= ((reg>>4)&0x1) << 22; - code |= (reg&0xf) << 0; - code |= ((reg>>4)&0x1) << 5; - code |= (shift&0xf) << 16; - code |= 0x40; - orc_arm_emit (compiler, code); - } - - return; } - ORC_COMPILER_ERROR(compiler, "unimplemented load of constant %d", value); } void orc_neon_emit_loadil (OrcCompiler *compiler, int reg, int value) { orc_uint32 code; - int shift; - int neg = FALSE; if (value == 0) { orc_neon_emit_binary_quad (compiler, "veor", 0xf3000110, reg, reg, reg); return; } - if (value < 0) { - neg = TRUE; - value = ~value; - } - shift = orc_neon_get_const_shift (value); - if ((value & (0xff<<shift)) == value) { - value >>= shift; - if (neg) { - ORC_ASM_CODE(compiler," vmvn.i32 %s, #%d\n", - orc_neon_reg_name_quad (reg), value); - code = 0xf2800030; - } else { - ORC_ASM_CODE(compiler," vmov.i32 %s, #%d\n", - orc_neon_reg_name_quad (reg), value); - code = 0xf2800010; - } + ORC_ASM_CODE(compiler," vmov.i32 %s, #0x%08x\n", + orc_neon_reg_name_quad (reg), value & 0xff); + code = 0xf2800010; + + code |= (reg&0xf) << 12; + code |= ((reg>>4)&0x1) << 22; + code |= (value&0xf) << 0; + code |= (value&0x70) << 12; + code |= (value&0x80) << 17; + code |= 0x40; + orc_arm_emit (compiler, code); + + value >>= 8; + if (value & 0xff) { + ORC_ASM_CODE(compiler," vorr.i32 %s, #0x%08x\n", + orc_neon_reg_name_quad (reg), (value & 0xff) << 8); + code = 0xf2800310; + code |= (reg&0xf) << 12; code |= ((reg>>4)&0x1) << 22; code |= (value&0xf) << 0; @@ -1140,24 +1125,35 @@ orc_neon_emit_loadil (OrcCompiler *compiler, int reg, int value) code |= (value&0x80) << 17; code |= 0x40; orc_arm_emit (compiler, code); + } + value >>= 8; + if (value & 0xff) { + ORC_ASM_CODE(compiler," vorr.i32 %s, #0x%08x\n", + orc_neon_reg_name_quad (reg), (value & 0xff) << 16); + code = 0xf2800510; - if (shift > 0) { - ORC_ASM_CODE(compiler," vshl.i32 %s, %s, #%d\n", - orc_neon_reg_name_quad (reg), orc_neon_reg_name_quad (reg), shift); - code = 0xf2a00510; - code |= (reg&0xf) << 12; - code |= ((reg>>4)&0x1) << 22; - code |= (reg&0xf) << 0; - code |= ((reg>>4)&0x1) << 5; - code |= (shift&0x1f) << 16; - code |= 0x40; - orc_arm_emit (compiler, code); - } - - return; + code |= (reg&0xf) << 12; + code |= ((reg>>4)&0x1) << 22; + code |= (value&0xf) << 0; + code |= (value&0x70) << 12; + code |= (value&0x80) << 17; + code |= 0x40; + orc_arm_emit (compiler, code); } + value >>= 8; + if (value & 0xff) { + ORC_ASM_CODE(compiler," vorr.i32 %s, #0x%08x\n", + orc_neon_reg_name_quad (reg), (value & 0xff) << 24); + code = 0xf2800710; - ORC_COMPILER_ERROR(compiler, "unimplemented load of constant %d", value); + code |= (reg&0xf) << 12; + code |= ((reg>>4)&0x1) << 22; + code |= (value&0xf) << 0; + code |= (value&0x70) << 12; + code |= (value&0x80) << 17; + code |= 0x40; + orc_arm_emit (compiler, code); + } } void |