From 80d74dbe0364f2ab8e4745958b3fa3e9ebd9191c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 29 Jan 2013 18:35:51 -0800 Subject: [PATCH] Implementing rlwimi. --- src/cpu/codegen/emit_alu.cc | 23 +++++++++++++++++++---- test/codegen/rlwimi.bin | Bin 0 -> 8 bytes test/codegen/rlwimi.dis | 9 +++++++++ test/codegen/rlwimi.s | 8 ++++++++ 4 files changed, 36 insertions(+), 4 deletions(-) create mode 100755 test/codegen/rlwimi.bin create mode 100644 test/codegen/rlwimi.dis create mode 100644 test/codegen/rlwimi.s diff --git a/src/cpu/codegen/emit_alu.cc b/src/cpu/codegen/emit_alu.cc index deb43e4d6..44a122674 100644 --- a/src/cpu/codegen/emit_alu.cc +++ b/src/cpu/codegen/emit_alu.cc @@ -1207,7 +1207,7 @@ XEEMITTER(rldicrx, 0x78000004, MD )(FunctionGenerator& g, IRBuilder<>& b, I XEDISASMR(rldimix, 0x7800000C, MD )(InstrData& i, InstrDisasm& d) { d.Init("rldimi", "Rotate Left Doubleword Immediate then Mask Insert", i.MD.Rc ? InstrDisasm::kRc : 0); - d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kReadWrite); d.AddRegOperand(InstrRegister::kGPR, i.MD.RT, InstrRegister::kRead); d.AddUImmOperand((i.MD.SH5 << 5) | i.MD.SH, 1); d.AddUImmOperand((i.MD.MB5 << 5) | i.MD.MB, 1); @@ -1221,7 +1221,7 @@ XEEMITTER(rldimix, 0x7800000C, MD )(FunctionGenerator& g, IRBuilder<>& b, I XEDISASMR(rlwimix, 0x50000000, M )(InstrData& i, InstrDisasm& d) { d.Init("rlwimi", "Rotate Left Word Immediate then Mask Insert", i.M.Rc ? InstrDisasm::kRc : 0); - d.AddRegOperand(InstrRegister::kGPR, i.M.RA, InstrRegister::kWrite); + d.AddRegOperand(InstrRegister::kGPR, i.M.RA, InstrRegister::kReadWrite); d.AddRegOperand(InstrRegister::kGPR, i.M.RT, InstrRegister::kRead); d.AddUImmOperand(i.M.SH, 1); d.AddUImmOperand(i.M.MB, 1); @@ -1233,8 +1233,23 @@ XEEMITTER(rlwimix, 0x50000000, M )(FunctionGenerator& g, IRBuilder<>& b, I // r <- ROTL32((RS)[32:63], n) // m <- MASK(MB+32, ME+32) // RA <- r&m | (RA)&¬m - XEINSTRNOTIMPLEMENTED(); - return 1; + + // ROTL32(x, y) = rotl(i64.(x||x), y) + Value* v = b.CreateAnd(g.gpr_value(i.M.RT), UINT32_MAX); + v = b.CreateOr(b.CreateShl(v, 32), v); + // (v << shift) | (v >> (32 - shift)); + v = b.CreateOr(b.CreateShl(v, i.M.SH), b.CreateLShr(v, 32 - i.M.SH)); + uint64_t m = XEMASK(i.M.MB + 32, i.M.ME + 32); + v = b.CreateAnd(v, m); + v = b.CreateOr(v, b.CreateAnd(g.gpr_value(i.M.RA), ~m)); + g.update_gpr_value(i.M.RA, v); + + if (i.M.Rc) { + // With cr0 update. + g.update_cr_with_cond(0, v, b.getInt64(0), true); + } + + return 0; } XEDISASMR(rlwinmx, 0x54000000, M )(InstrData& i, InstrDisasm& d) { diff --git a/test/codegen/rlwimi.bin b/test/codegen/rlwimi.bin new file mode 100755 index 0000000000000000000000000000000000000000..e83c8e941674d4b02f0a8e229ec17ecd4125dfb8 GIT binary patch literal 8 PcmWG&6R`4YU{C-63XB2| literal 0 HcmV?d00001 diff --git a/test/codegen/rlwimi.dis b/test/codegen/rlwimi.dis new file mode 100644 index 000000000..4c44f64c6 --- /dev/null +++ b/test/codegen/rlwimi.dis @@ -0,0 +1,9 @@ + +rlwimi.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000082010000 <.text>: + 82010000: 50 86 10 3a rlwimi r6,r4,2,0,29 + 82010004: 4e 80 00 20 blr diff --git a/test/codegen/rlwimi.s b/test/codegen/rlwimi.s new file mode 100644 index 000000000..253fa6f52 --- /dev/null +++ b/test/codegen/rlwimi.s @@ -0,0 +1,8 @@ +# REGISTER_IN r4 0xCAFEBABE90003000 +# REGISTER_IN r6 0xDEADBEEF00000003 + +rlwimi r6, r4, 2, 0, 0x1D + +blr +# REGISTER_OUT r4 0xCAFEBABE90003000 +# REGISTER_OUT r6 0xDEADBEEF4000C003