+CopyB => {
+ op_flags => "F|H",
+ state => "pinned",
+ reg_req => { in => [ "edi", "esi", "ecx", "none" ], out => [ "edi", "esi", "ecx", "none" ] },
+ outs => [ "DST", "SRC", "CNT", "M" ],
+ units => [ "GP" ],
+# we don't care about this flag, so no need to mark this node
+# modified_flags => [ "DF" ]
+},
+
+CopyB_i => {
+ op_flags => "F|H",
+ state => "pinned",
+ reg_req => { in => [ "edi", "esi", "none" ], out => [ "edi", "esi", "none" ] },
+ outs => [ "DST", "SRC", "M" ],
+ units => [ "GP" ],
+# we don't care about this flag, so no need to mark this node
+# modified_flags => [ "DF" ]
+},
+
+# Conversions
+
+Conv_I2I => {
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "gp", "none" ] },
+ ins => [ "base", "index", "mem", "val" ],
+ units => [ "GP" ],
+ attr => "ir_mode *smaller_mode",
+ init_attr => "attr->ls_mode = smaller_mode;",
+ mode => $mode_gp,
+},
+
+Conv_I2I8Bit => {
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "gp", "none" ] },
+ ins => [ "base", "index", "mem", "val" ],
+ units => [ "GP" ],
+ attr => "ir_mode *smaller_mode",
+ init_attr => "attr->ls_mode = smaller_mode;",
+ mode => $mode_gp,
+},
+
+Conv_I2FP => {
+ reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
+ ins => [ "base", "index", "mem", "val" ],
+ latency => 10,
+ units => [ "SSE" ],
+ mode => "mode_E",
+},
+
+Conv_FP2I => {
+ reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
+ ins => [ "base", "index", "mem", "val" ],
+ latency => 10,
+ units => [ "SSE" ],
+ mode => $mode_gp,
+},
+
+Conv_FP2FP => {
+ reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
+ ins => [ "base", "index", "mem", "val" ],
+ latency => 8,
+ units => [ "SSE" ],
+ mode => "mode_E",
+},
+
+#----------------------------------------------------------#
+# _ _ _ __ _ _ #
+# (_) | | | | / _| | | | #
+# __ ___ _ __| |_ _ _ __ _| | | |_| | ___ __ _| |_ #
+# \ \ / / | '__| __| | | |/ _` | | | _| |/ _ \ / _` | __| #
+# \ V /| | | | |_| |_| | (_| | | | | | | (_) | (_| | |_ #
+# \_/ |_|_| \__|\__,_|\__,_|_| |_| |_|\___/ \__,_|\__| #
+# | | #
+# _ __ ___ __| | ___ ___ #
+# | '_ \ / _ \ / _` |/ _ \/ __| #
+# | | | | (_) | (_| | __/\__ \ #
+# |_| |_|\___/ \__,_|\___||___/ #
+#----------------------------------------------------------#
+
+vfadd => {
+ irn_flags => "R",
+ reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
+ ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
+ latency => 4,
+ units => [ "VFP" ],
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
+},
+
+vfmul => {
+ irn_flags => "R",
+ reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
+ ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
+ latency => 4,
+ units => [ "VFP" ],
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
+},
+
+l_vfmul => {
+ op_flags => "C",
+ cmp_attr => "return 1;",
+ arity => 2,
+},
+
+vfsub => {
+ irn_flags => "R",
+ reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
+ ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
+ latency => 4,
+ units => [ "VFP" ],
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
+},
+
+l_vfsub => {
+ cmp_attr => "return 1;",
+ arity => 2,
+},
+
+vfdiv => {
+ reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp", "none" ] },
+ ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
+ outs => [ "res", "M" ],
+ latency => 20,
+ units => [ "VFP" ],
+ attr_type => "ia32_x87_attr_t",
+},
+
+l_vfdiv => {
+ cmp_attr => "return 1;",
+ outs => [ "res", "M" ],
+ arity => 2,
+},
+
+vfprem => {
+ reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
+ ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
+ latency => 20,
+ units => [ "VFP" ],
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
+},
+
+l_vfprem => {
+ cmp_attr => "return 1;",
+ arity => 2,
+},
+
+vfabs => {
+ irn_flags => "R",
+ reg_req => { in => [ "vfp"], out => [ "vfp" ] },
+ ins => [ "value" ],
+ latency => 2,
+ units => [ "VFP" ],
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
+},
+
+vfchs => {
+ irn_flags => "R",
+ reg_req => { in => [ "vfp"], out => [ "vfp" ] },
+ ins => [ "value" ],
+ latency => 2,
+ units => [ "VFP" ],
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
+},
+
+# virtual Load and Store
+
+vfld => {
+ op_flags => "L|F",
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] },
+ ins => [ "base", "index", "mem" ],
+ outs => [ "res", "M" ],
+ attr => "ir_mode *load_mode",
+ init_attr => "attr->attr.ls_mode = load_mode;",
+ latency => 2,
+ units => [ "VFP" ],
+ attr_type => "ia32_x87_attr_t",
+},
+
+vfst => {
+ op_flags => "L|F",
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "vfp" ] },
+ ins => [ "base", "index", "mem", "val" ],
+ attr => "ir_mode *store_mode",
+ init_attr => "attr->attr.ls_mode = store_mode;",
+ latency => 2,
+ units => [ "VFP" ],
+ mode => "mode_M",
+ attr_type => "ia32_x87_attr_t",
+},
+
+# Conversions
+
+vfild => {
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] },
+ outs => [ "res", "M" ],
+ ins => [ "base", "index", "mem" ],
+ latency => 4,
+ units => [ "VFP" ],
+ attr_type => "ia32_x87_attr_t",
+},
+
+l_vfild => {
+ cmp_attr => "return 1;",
+ outs => [ "res", "M" ],
+ arity => 2,
+},
+
+vfist => {
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "vfp", "fpcw" ] },
+ ins => [ "base", "index", "mem", "val", "fpcw" ],
+ latency => 4,
+ units => [ "VFP" ],
+ mode => "mode_M",
+ attr_type => "ia32_x87_attr_t",
+},
+
+l_vfist => {
+ cmp_attr => "return 1;",
+ state => "exc_pinned",
+ arity => 3,
+ mode => "mode_M",
+},
+
+
+# constants
+
+vfldz => {
+ irn_flags => "R",
+ reg_req => { out => [ "vfp" ] },
+ latency => 4,
+ units => [ "VFP" ],
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
+},
+
+vfld1 => {
+ irn_flags => "R",
+ reg_req => { out => [ "vfp" ] },
+ latency => 4,
+ units => [ "VFP" ],
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
+},
+
+vfldpi => {
+ irn_flags => "R",
+ reg_req => { out => [ "vfp" ] },
+ latency => 4,
+ units => [ "VFP" ],
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
+},
+
+vfldln2 => {
+ irn_flags => "R",
+ reg_req => { out => [ "vfp" ] },
+ latency => 4,
+ units => [ "VFP" ],
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
+},
+
+vfldlg2 => {
+ irn_flags => "R",
+ reg_req => { out => [ "vfp" ] },
+ latency => 4,
+ units => [ "VFP" ],
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
+},
+
+vfldl2t => {
+ irn_flags => "R",
+ reg_req => { out => [ "vfp" ] },
+ latency => 4,
+ units => [ "VFP" ],
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
+},
+
+vfldl2e => {
+ irn_flags => "R",
+ reg_req => { out => [ "vfp" ] },
+ latency => 4,
+ units => [ "VFP" ],
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
+},
+
+# other
+
+vFucomFnstsw => {
+# we can't allow to rematerialize this node so we don't have
+# accidently produce Phi(Fucom, Fucom(flipped))
+# irn_flags => "R",
+ reg_req => { in => [ "vfp", "vfp" ], out => [ "eax" ] },
+ ins => [ "left", "right" ],
+ outs => [ "flags" ],
+ am => "source,binary",
+ attr => "int flipped",
+ init_attr => "attr->attr.data.cmp_flipped = flipped;",
+ latency => 3,
+ units => [ "VFP" ],
+ attr_type => "ia32_x87_attr_t",
+ mode => $mode_gp
+},
+
+Sahf => {
+ irn_flags => "R",
+ reg_req => { in => [ "eax" ], out => [ "eflags" ] },
+ ins => [ "val" ],
+ outs => [ "flags" ],
+ emit => '. sahf',
+ units => [ "GP" ],
+ mode => $mode_flags,
+},
+
+#------------------------------------------------------------------------#
+# ___ _____ __ _ _ _ #
+# __ _( _ )___ | / _| | ___ __ _| |_ _ __ ___ __| | ___ ___ #
+# \ \/ / _ \ / / | |_| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
+# > < (_) |/ / | _| | (_) | (_| | |_ | | | | (_) | (_| | __/\__ \ #
+# /_/\_\___//_/ |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
+#------------------------------------------------------------------------#
+
+# Note: gas is strangely buggy: fdivrp and fdivp as well as fsubrp and fsubp
+# are swapped, we work this around in the emitter...
+
+fadd => {
+ op_flags => "R",
+ rd_constructor => "NONE",
+ reg_req => { },
+ emit => '. fadd%XM %x87_binop',
+ attr_type => "ia32_x87_attr_t",
+},
+
+faddp => {
+ op_flags => "R",
+ rd_constructor => "NONE",
+ reg_req => { },
+ emit => '. faddp%XM %x87_binop',
+ attr_type => "ia32_x87_attr_t",
+},
+
+fmul => {
+ op_flags => "R",
+ rd_constructor => "NONE",
+ reg_req => { },
+ emit => '. fmul%XM %x87_binop',
+ attr_type => "ia32_x87_attr_t",
+},
+
+fmulp => {
+ op_flags => "R",
+ rd_constructor => "NONE",
+ reg_req => { },
+ emit => '. fmulp%XM %x87_binop',,
+ attr_type => "ia32_x87_attr_t",
+},
+
+fsub => {
+ op_flags => "R",
+ rd_constructor => "NONE",
+ reg_req => { },
+ emit => '. fsub%XM %x87_binop',
+ attr_type => "ia32_x87_attr_t",
+},
+
+fsubp => {
+ op_flags => "R",
+ rd_constructor => "NONE",
+ reg_req => { },
+# see note about gas bugs
+ emit => '. fsubrp%XM %x87_binop',
+ attr_type => "ia32_x87_attr_t",
+},
+
+fsubr => {
+ op_flags => "R",
+ rd_constructor => "NONE",
+ irn_flags => "R",
+ reg_req => { },
+ emit => '. fsubr%XM %x87_binop',
+ attr_type => "ia32_x87_attr_t",
+},
+
+fsubrp => {
+ op_flags => "R",
+ rd_constructor => "NONE",
+ irn_flags => "R",
+ reg_req => { },
+# see note about gas bugs
+ emit => '. fsubp%XM %x87_binop',
+ attr_type => "ia32_x87_attr_t",
+},
+
+fprem => {
+ op_flags => "R",
+ rd_constructor => "NONE",
+ reg_req => { },
+ emit => '. fprem1',
+ attr_type => "ia32_x87_attr_t",
+},
+
+# this node is just here, to keep the simulator running
+# we can omit this when a fprem simulation function exists
+fpremp => {
+ op_flags => "R",
+ rd_constructor => "NONE",
+ reg_req => { },
+ emit => '. fprem1',
+ attr_type => "ia32_x87_attr_t",