sparc: support float perms
authorMatthias Braun <matthias.braun@kit.edu>
Thu, 9 Aug 2012 10:04:59 +0000 (12:04 +0200)
committerMatthias Braun <matthias.braun@kit.edu>
Thu, 9 Aug 2012 16:35:18 +0000 (18:35 +0200)
ir/be/sparc/sparc_cconv.c
ir/be/sparc/sparc_emitter.c

index c94fa45..cccf569 100644 (file)
@@ -51,6 +51,8 @@ static const unsigned ignore_regs[] = {
        REG_FPFLAGS,
        REG_FLAGS,
        REG_Y,
+
+       REG_F31,
 };
 
 static const arch_register_t* const param_regs[] = {
@@ -117,7 +119,6 @@ static const unsigned caller_saves[] = {
        REG_F28,
        REG_F29,
        REG_F30,
-       REG_F31,
        REG_FLAGS,
        REG_FPFLAGS,
        REG_Y,
index 0af1f40..b8ad1c3 100644 (file)
@@ -798,9 +798,25 @@ static void emit_sparc_Call(const ir_node *node)
 
 static void emit_be_Perm(const ir_node *irn)
 {
-       sparc_emitf(irn, "xor %S1, %S0, %S0");
-       sparc_emitf(irn, "xor %S1, %S0, %S1");
-       sparc_emitf(irn, "xor %S1, %S0, %S0");
+       ir_mode *mode = get_irn_mode(get_irn_n(irn, 0));
+       if (mode_is_float(mode)) {
+               const arch_register_t *reg0 = arch_get_irn_register_in(irn, 0);
+               const arch_register_t *reg1 = arch_get_irn_register_in(irn, 1);
+               unsigned reg_idx0 = reg0->global_index;
+               unsigned reg_idx1 = reg1->global_index;
+               unsigned width    = arch_get_irn_register_req_in(irn, 0)->width;
+               for (unsigned i = 0; i < width; ++i) {
+                       const arch_register_t *r0 = &sparc_registers[reg_idx0+i];
+                       const arch_register_t *r1 = &sparc_registers[reg_idx1+i];
+                       sparc_emitf(irn, "fmovs %R, %%f31", r0);
+                       sparc_emitf(irn, "fmovs %R, %R", r1, r0);
+                       sparc_emitf(irn, "fmovs %%f31, %R", r1);
+               }
+       } else {
+               sparc_emitf(irn, "xor %S1, %S0, %S0");
+               sparc_emitf(irn, "xor %S1, %S0, %S1");
+               sparc_emitf(irn, "xor %S1, %S0, %S0");
+       }
 }
 
 /* The stack pointer must always be SPARC_STACK_ALIGNMENT bytes aligned, so get