+/**
+ * Transform builtin byte swap.
+ */
+static ir_node *gen_bswap(ir_node *node) {
+ ir_node *param = be_transform_node(get_Builtin_param(node, 0));
+ dbg_info *dbgi = get_irn_dbg_info(node);
+
+ ir_node *block = get_nodes_block(node);
+ ir_node *new_block = be_transform_node(block);
+ ir_mode *mode = get_irn_mode(param);
+ unsigned size = get_mode_size_bits(mode);
+ ir_node *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4, *noreg, *nomem;
+
+ switch (size) {
+ case 32:
+ if (ia32_cg_config.use_i486) {
+ /* swap available */
+ return new_bd_ia32_Bswap(dbgi, new_block, param);
+ }
+ s1 = new_bd_ia32_Shl(dbgi, new_block, param, create_Immediate(NULL, 0, 24));
+ s2 = new_bd_ia32_Shl(dbgi, new_block, param, create_Immediate(NULL, 0, 8));
+
+ noreg = ia32_new_NoReg_gp(env_cg);
+ nomem = new_NoMem();
+
+ m1 = new_bd_ia32_And(dbgi, new_block, noreg, noreg, nomem, s2, create_Immediate(NULL, 0, 0xFF00));
+ m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
+
+ s3 = new_bd_ia32_Shr(dbgi, new_block, param, create_Immediate(NULL, 0, 8));
+
+ m3 = new_bd_ia32_And(dbgi, new_block, noreg, noreg, nomem, s3, create_Immediate(NULL, 0, 0xFF0000));
+ m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
+
+ s4 = new_bd_ia32_Shr(dbgi, new_block, param, create_Immediate(NULL, 0, 24));
+ return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
+
+ case 16:
+ /* swap16 always available */
+ return new_bd_ia32_Bswap16(dbgi, new_block, param);
+
+ default:
+ panic("Invalid bswap size (%d)", size);
+ }
+}
+