else
new_op = new_rd_ia32_vfld(dbg, irg, block, ptr, noreg, mem);
}
+ else if (get_mode_size_bits(spillmode) == 128) {
+ // Reload 128 bit sse registers
+ new_op = new_rd_ia32_xxLoad(dbg, irg, block, ptr, noreg, mem);
+ }
else
new_op = new_rd_ia32_Load(dbg, irg, block, ptr, noreg, mem);
else
store = new_rd_ia32_vfst(dbg, irg, block, ptr, noreg, val, nomem);
}
+ else if (get_mode_size_bits(mode) == 128) {
+ // Spill 128 bit SSE registers
+ store = new_rd_ia32_xxStore(dbg, irg, block, ptr, noreg, val, nomem);
+ }
else if (get_mode_size_bits(mode) == 8) {
store = new_rd_ia32_Store8Bit(dbg, irg, block, ptr, noreg, val, nomem);
}
* - the general purpose registers
* - the SSE floating point register set
* - the virtual floating point registers
+ * - the SSE vector register set
*/
static int ia32_get_n_reg_class(const void *self) {
return 3;
* Return the register class for index i.
*/
static const arch_register_class_t *ia32_get_reg_class(const void *self, int i) {
- assert(i >= 0 && i < 3 && "Invalid ia32 register class requested.");
- if (i == 0)
- return &ia32_reg_classes[CLASS_ia32_gp];
- else if (i == 1)
- return &ia32_reg_classes[CLASS_ia32_xmm];
- else
- return &ia32_reg_classes[CLASS_ia32_vfp];
+ switch (i) {
+ case 0:
+ return &ia32_reg_classes[CLASS_ia32_gp];
+ case 1:
+ return &ia32_reg_classes[CLASS_ia32_xmm];
+ case 2:
+ return &ia32_reg_classes[CLASS_ia32_vfp];
+ default:
+ assert(0 && "Invalid ia32 register class requested.");
+ return NULL;
+ }
}
/**
{ "name" => "xmm5", "type" => 1 },
{ "name" => "xmm6", "type" => 1 },
{ "name" => "xmm7", "type" => 1 },
- { "name" => "xmm_NOREG", "type" => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes
- { "name" => "xmm_UKNWN", "type" => 4 | 8 | 16 }, # we need a dummy register for Unknown nodes
- { "mode" => "mode_E" }
+ { "name" => "xmm_NOREG", "type" => 4 | 16 }, # we need a dummy register for NoReg nodes
+ { "name" => "xmm_UKNWN", "type" => 4 | 8 | 16}, # we need a dummy register for Unknown nodes
+ { "mode" => "mode_DLu" }
],
"vfp" => [
{ "name" => "vf0", "type" => 1 | 16 },
{ "name" => "fpcw", "type" => 0 },
{ "mode" => "mode_Hu" },
],
+
); # %reg_classes
%cpu = (
"reg_req" => { },
},
+
+# -------------------------------------------------------------------------------- #
+# ____ ____ _____ _ _ #
+# / ___/ ___|| ____| __ _____ ___| |_ ___ _ __ _ __ ___ __| | ___ ___ #
+# \___ \___ \| _| \ \ / / _ \/ __| __/ _ \| '__| | '_ \ / _ \ / _` |/ _ \/ __| #
+# ___) |__) | |___ \ V / __/ (__| || (_) | | | | | | (_) | (_| | __/\__ \ #
+# |____/____/|_____| \_/ \___|\___|\__\___/|_| |_| |_|\___/ \__,_|\___||___/ #
+# #
+# -------------------------------------------------------------------------------- #
+
+
+# Spilling and reloading of SSE registers, hardcoded, not generated #
+
+"xxLoad" => {
+ "op_flags" => "L|F",
+ "state" => "exc_pinned",
+ "comment" => "construct SSE Load: Load(ptr, mem) = LD ptr",
+ "reg_req" => { "in" => [ "gp", "gp", "none" ], "out" => [ "xmm", "none" ] },
+ "emit" => '. movdqu %D1, %AM',
+ "outs" => [ "res", "M" ],
+ "units" => [ "SSE" ],
+},
+
+"xxStore" => {
+ "op_flags" => "L|F",
+ "state" => "exc_pinned",
+ "comment" => "construct Store: Store(ptr, val, mem) = ST ptr,val",
+ "reg_req" => { "in" => [ "gp", "gp", "xmm", "none" ] },
+ "emit" => '. movdqu %binop',
+ "units" => [ "SSE" ],
+ "mode" => "mode_M",
+},
+
); # end of %nodes
+
+# Include the generated SIMD node specification written by the SIMD optimization
+
+do "../ir/be/ia32/ia32_simd_spec.pl";