diff --git a/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc b/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc index 2fd78884f..54d9ac836 100644 --- a/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc +++ b/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc @@ -350,7 +350,7 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) { case OPCODE_DIV: if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { v->set_from(i->src1.value); - v->Div(i->src2.value); + v->Div(i->src2.value, (i->flags & ARITHMETIC_UNSIGNED) != 0); i->Remove(); } break; diff --git a/src/xenia/cpu/frontend/test/bin/instr_divw.bin b/src/xenia/cpu/frontend/test/bin/instr_divw.bin index 3eea99d95..c0e229e23 100644 Binary files a/src/xenia/cpu/frontend/test/bin/instr_divw.bin and b/src/xenia/cpu/frontend/test/bin/instr_divw.bin differ diff --git a/src/xenia/cpu/frontend/test/bin/instr_divw.dis b/src/xenia/cpu/frontend/test/bin/instr_divw.dis index dc362e72a..0250d8426 100644 --- a/src/xenia/cpu/frontend/test/bin/instr_divw.dis +++ b/src/xenia/cpu/frontend/test/bin/instr_divw.dis @@ -4,38 +4,101 @@ Disassembly of section .text: 100000: 7c 64 2b d6 divw r3,r4,r5 100004: 4e 80 00 20 blr -0000000000100008 : - 100008: 7c 64 2b d6 divw r3,r4,r5 - 10000c: 4e 80 00 20 blr - -0000000000100010 : +0000000000100008 : + 100008: 38 80 00 01 li r4,1 + 10000c: 38 a0 00 02 li r5,2 100010: 7c 64 2b d6 divw r3,r4,r5 100014: 4e 80 00 20 blr -0000000000100018 : +0000000000100018 : 100018: 7c 64 2b d6 divw r3,r4,r5 10001c: 4e 80 00 20 blr -0000000000100020 : - 100020: 7c 64 2b d6 divw r3,r4,r5 - 100024: 4e 80 00 20 blr - -0000000000100028 : +0000000000100020 : + 100020: 38 80 00 02 li r4,2 + 100024: 38 a0 00 01 li r5,1 100028: 7c 64 2b d6 divw r3,r4,r5 10002c: 4e 80 00 20 blr -0000000000100030 : +0000000000100030 : 100030: 7c 64 2b d6 divw r3,r4,r5 100034: 4e 80 00 20 blr -0000000000100038 : - 100038: 7c 64 2b d6 divw r3,r4,r5 - 10003c: 4e 80 00 20 blr - -0000000000100040 : +0000000000100038 : + 100038: 38 80 00 23 li r4,35 + 10003c: 38 a0 00 07 li r5,7 100040: 7c 64 2b d6 divw r3,r4,r5 100044: 4e 80 00 20 blr -0000000000100048 : +0000000000100048 : 100048: 7c 64 2b d6 divw r3,r4,r5 10004c: 4e 80 00 20 blr + +0000000000100050 : + 100050: 38 80 00 00 li r4,0 + 100054: 38 a0 00 01 li r5,1 + 100058: 7c 64 2b d6 divw r3,r4,r5 + 10005c: 4e 80 00 20 blr + +0000000000100060 : + 100060: 7c 64 2b d6 divw r3,r4,r5 + 100064: 4e 80 00 20 blr + +0000000000100068 : + 100068: 38 80 ff ff li r4,-1 + 10006c: 38 a0 00 01 li r5,1 + 100070: 7c 64 2b d6 divw r3,r4,r5 + 100074: 4e 80 00 20 blr + +0000000000100078 : + 100078: 7c 64 2b d6 divw r3,r4,r5 + 10007c: 4e 80 00 20 blr + +0000000000100080 : + 100080: 38 80 ff ff li r4,-1 + 100084: 38 a0 ff ff li r5,-1 + 100088: 7c 64 2b d6 divw r3,r4,r5 + 10008c: 4e 80 00 20 blr + +0000000000100090 : + 100090: 7c 64 2b d6 divw r3,r4,r5 + 100094: 4e 80 00 20 blr + +0000000000100098 : + 100098: 38 80 00 01 li r4,1 + 10009c: 38 a0 ff ff li r5,-1 + 1000a0: 7c 64 2b d6 divw r3,r4,r5 + 1000a4: 4e 80 00 20 blr + +00000000001000a8 : + 1000a8: 7c 64 2b d6 divw r3,r4,r5 + 1000ac: 4e 80 00 20 blr + +00000000001000b0 : + 1000b0: 38 80 ff ff li r4,-1 + 1000b4: 78 84 00 60 clrldi r4,r4,33 + 1000b8: 38 a0 00 01 li r5,1 + 1000bc: 7c 64 2b d6 divw r3,r4,r5 + 1000c0: 4e 80 00 20 blr + +00000000001000c4 : + 1000c4: 7c 64 2b d6 divw r3,r4,r5 + 1000c8: 4e 80 00 20 blr + +00000000001000cc : + 1000cc: 38 80 ff ff li r4,-1 + 1000d0: 78 84 00 60 clrldi r4,r4,33 + 1000d4: 7c 85 23 78 mr r5,r4 + 1000d8: 7c 64 2b d6 divw r3,r4,r5 + 1000dc: 4e 80 00 20 blr + +00000000001000e0 : + 1000e0: 7c 64 2b d6 divw r3,r4,r5 + 1000e4: 4e 80 00 20 blr + +00000000001000e8 : + 1000e8: 38 80 00 01 li r4,1 + 1000ec: 38 a0 ff ff li r5,-1 + 1000f0: 78 a5 00 60 clrldi r5,r5,33 + 1000f4: 7c 64 2b d6 divw r3,r4,r5 + 1000f8: 4e 80 00 20 blr diff --git a/src/xenia/cpu/frontend/test/bin/instr_divw.map b/src/xenia/cpu/frontend/test/bin/instr_divw.map index 2eb54045f..87d6ff948 100644 --- a/src/xenia/cpu/frontend/test/bin/instr_divw.map +++ b/src/xenia/cpu/frontend/test/bin/instr_divw.map @@ -1,10 +1,20 @@ 0000000000000000 t test_divw_1 -0000000000000008 t test_divw_3 -0000000000000010 t test_divw_4 -0000000000000018 t test_divw_5 -0000000000000020 t test_divw_6 -0000000000000028 t test_divw_7 -0000000000000030 t test_divw_8 -0000000000000038 t test_divw_9 -0000000000000040 t test_divw_10 -0000000000000048 t test_divw_11 +0000000000000008 t test_divw_1_constant +0000000000000018 t test_divw_3 +0000000000000020 t test_divw_3_constant +0000000000000030 t test_divw_4 +0000000000000038 t test_divw_4_constant +0000000000000048 t test_divw_5 +0000000000000050 t test_divw_5_constant +0000000000000060 t test_divw_6 +0000000000000068 t test_divw_6_constant +0000000000000078 t test_divw_7 +0000000000000080 t test_divw_7_constant +0000000000000090 t test_divw_8 +0000000000000098 t test_divw_8_constant +00000000000000a8 t test_divw_9 +00000000000000b0 t test_divw_9_constant +00000000000000c4 t test_divw_10 +00000000000000cc t test_divw_10_constant +00000000000000e0 t test_divw_11 +00000000000000e8 t test_divw_11_constant diff --git a/src/xenia/cpu/frontend/test/bin/instr_divwu.bin b/src/xenia/cpu/frontend/test/bin/instr_divwu.bin index 0cf0fe52b..61d466e46 100644 Binary files a/src/xenia/cpu/frontend/test/bin/instr_divwu.bin and b/src/xenia/cpu/frontend/test/bin/instr_divwu.bin differ diff --git a/src/xenia/cpu/frontend/test/bin/instr_divwu.dis b/src/xenia/cpu/frontend/test/bin/instr_divwu.dis index 69d58bdb0..6d516dd25 100644 --- a/src/xenia/cpu/frontend/test/bin/instr_divwu.dis +++ b/src/xenia/cpu/frontend/test/bin/instr_divwu.dis @@ -4,42 +4,112 @@ Disassembly of section .text: 100000: 7c 64 2b 96 divwu r3,r4,r5 100004: 4e 80 00 20 blr -0000000000100008 : - 100008: 7c 64 2b 96 divwu r3,r4,r5 - 10000c: 4e 80 00 20 blr - -0000000000100010 : +0000000000100008 : + 100008: 38 80 00 01 li r4,1 + 10000c: 38 a0 00 02 li r5,2 100010: 7c 64 2b 96 divwu r3,r4,r5 100014: 4e 80 00 20 blr -0000000000100018 : +0000000000100018 : 100018: 7c 64 2b 96 divwu r3,r4,r5 10001c: 4e 80 00 20 blr -0000000000100020 : - 100020: 7c 64 2b 96 divwu r3,r4,r5 - 100024: 4e 80 00 20 blr - -0000000000100028 : +0000000000100020 : + 100020: 38 80 00 02 li r4,2 + 100024: 38 a0 00 01 li r5,1 100028: 7c 64 2b 96 divwu r3,r4,r5 10002c: 4e 80 00 20 blr -0000000000100030 : +0000000000100030 : 100030: 7c 64 2b 96 divwu r3,r4,r5 100034: 4e 80 00 20 blr -0000000000100038 : - 100038: 7c 64 2b 96 divwu r3,r4,r5 - 10003c: 4e 80 00 20 blr - -0000000000100040 : +0000000000100038 : + 100038: 38 80 00 23 li r4,35 + 10003c: 38 a0 00 07 li r5,7 100040: 7c 64 2b 96 divwu r3,r4,r5 100044: 4e 80 00 20 blr -0000000000100048 : +0000000000100048 : 100048: 7c 64 2b 96 divwu r3,r4,r5 10004c: 4e 80 00 20 blr -0000000000100050 : - 100050: 7c 64 2b 96 divwu r3,r4,r5 - 100054: 4e 80 00 20 blr +0000000000100050 : + 100050: 38 80 00 00 li r4,0 + 100054: 38 a0 00 01 li r5,1 + 100058: 7c 64 2b 96 divwu r3,r4,r5 + 10005c: 4e 80 00 20 blr + +0000000000100060 : + 100060: 7c 64 2b 96 divwu r3,r4,r5 + 100064: 4e 80 00 20 blr + +0000000000100068 : + 100068: 38 80 ff ff li r4,-1 + 10006c: 38 a0 00 01 li r5,1 + 100070: 7c 64 2b 96 divwu r3,r4,r5 + 100074: 4e 80 00 20 blr + +0000000000100078 : + 100078: 7c 64 2b 96 divwu r3,r4,r5 + 10007c: 4e 80 00 20 blr + +0000000000100080 : + 100080: 38 80 ff ff li r4,-1 + 100084: 38 a0 ff ff li r5,-1 + 100088: 7c 64 2b 96 divwu r3,r4,r5 + 10008c: 4e 80 00 20 blr + +0000000000100090 : + 100090: 7c 64 2b 96 divwu r3,r4,r5 + 100094: 4e 80 00 20 blr + +0000000000100098 : + 100098: 38 80 00 01 li r4,1 + 10009c: 38 a0 ff ff li r5,-1 + 1000a0: 7c 64 2b 96 divwu r3,r4,r5 + 1000a4: 4e 80 00 20 blr + +00000000001000a8 : + 1000a8: 7c 64 2b 96 divwu r3,r4,r5 + 1000ac: 4e 80 00 20 blr + +00000000001000b0 : + 1000b0: 38 80 ff ff li r4,-1 + 1000b4: 78 84 00 60 clrldi r4,r4,33 + 1000b8: 38 a0 00 01 li r5,1 + 1000bc: 7c 64 2b 96 divwu r3,r4,r5 + 1000c0: 4e 80 00 20 blr + +00000000001000c4 : + 1000c4: 7c 64 2b 96 divwu r3,r4,r5 + 1000c8: 4e 80 00 20 blr + +00000000001000cc : + 1000cc: 38 80 ff ff li r4,-1 + 1000d0: 78 84 00 60 clrldi r4,r4,33 + 1000d4: 7c 85 23 78 mr r5,r4 + 1000d8: 7c 64 2b 96 divwu r3,r4,r5 + 1000dc: 4e 80 00 20 blr + +00000000001000e0 : + 1000e0: 7c 64 2b 96 divwu r3,r4,r5 + 1000e4: 4e 80 00 20 blr + +00000000001000e8 : + 1000e8: 38 80 00 01 li r4,1 + 1000ec: 38 a0 ff ff li r5,-1 + 1000f0: 78 a5 00 60 clrldi r5,r5,33 + 1000f4: 7c 64 2b 96 divwu r3,r4,r5 + 1000f8: 4e 80 00 20 blr + +00000000001000fc : + 1000fc: 7c 64 2b 96 divwu r3,r4,r5 + 100100: 4e 80 00 20 blr + +0000000000100104 : + 100104: 38 80 00 01 li r4,1 + 100108: 78 84 f8 24 rldicr r4,r4,31,32 + 10010c: 38 a0 ff ff li r5,-1 + 100110: 7c 64 2b 96 divwu r3,r4,r5 + 100114: 4e 80 00 20 blr diff --git a/src/xenia/cpu/frontend/test/bin/instr_divwu.map b/src/xenia/cpu/frontend/test/bin/instr_divwu.map index e4561f993..c5704f874 100644 --- a/src/xenia/cpu/frontend/test/bin/instr_divwu.map +++ b/src/xenia/cpu/frontend/test/bin/instr_divwu.map @@ -1,11 +1,22 @@ 0000000000000000 t test_divwu_1 -0000000000000008 t test_divwu_3 -0000000000000010 t test_divwu_4 -0000000000000018 t test_divwu_5 -0000000000000020 t test_divwu_6 -0000000000000028 t test_divwu_7 -0000000000000030 t test_divwu_8 -0000000000000038 t test_divwu_9 -0000000000000040 t test_divwu_10 -0000000000000048 t test_divwu_11 -0000000000000050 t test_divwu_12 +0000000000000008 t test_divwu_1_constant +0000000000000018 t test_divwu_3 +0000000000000020 t test_divwu_3_constant +0000000000000030 t test_divwu_4 +0000000000000038 t test_divwu_4_constant +0000000000000048 t test_divwu_5 +0000000000000050 t test_divwu_5_constant +0000000000000060 t test_divwu_6 +0000000000000068 t test_divwu_6_constant +0000000000000078 t test_divwu_7 +0000000000000080 t test_divwu_7_constant +0000000000000090 t test_divwu_8 +0000000000000098 t test_divwu_8_constant +00000000000000a8 t test_divwu_9 +00000000000000b0 t test_divwu_9_constant +00000000000000c4 t test_divwu_10 +00000000000000cc t test_divwu_10_constant +00000000000000e0 t test_divwu_11 +00000000000000e8 t test_divwu_11_constant +00000000000000fc t test_divwu_12 +0000000000000104 t test_divwu_12_constant diff --git a/src/xenia/cpu/hir/value.cc b/src/xenia/cpu/hir/value.cc index 80d2f6415..c08f2b196 100644 --- a/src/xenia/cpu/hir/value.cc +++ b/src/xenia/cpu/hir/value.cc @@ -304,20 +304,36 @@ void Value::Mul(Value* other) { } } -void Value::Div(Value* other) { +void Value::Div(Value* other, bool is_unsigned) { assert_true(type == other->type); switch (type) { case INT8_TYPE: - constant.i8 /= uint8_t(other->constant.i8); + if (is_unsigned) { + constant.i8 /= uint8_t(other->constant.i8); + } else { + constant.i8 /= other->constant.i8; + } break; case INT16_TYPE: - constant.i16 /= uint16_t(other->constant.i16); + if (is_unsigned) { + constant.i16 /= uint16_t(other->constant.i16); + } else { + constant.i16 /= other->constant.i16; + } break; case INT32_TYPE: - constant.i32 /= uint32_t(other->constant.i32); + if (is_unsigned) { + constant.i32 /= uint32_t(other->constant.i32); + } else { + constant.i32 /= other->constant.i32; + } break; case INT64_TYPE: - constant.i64 /= uint64_t(other->constant.i64); + if (is_unsigned) { + constant.i64 /= uint64_t(other->constant.i64); + } else { + constant.i64 /= other->constant.i64; + } break; case FLOAT32_TYPE: constant.f32 /= other->constant.f32; diff --git a/src/xenia/cpu/hir/value.h b/src/xenia/cpu/hir/value.h index c9be576fc..0fc4cfcf6 100644 --- a/src/xenia/cpu/hir/value.h +++ b/src/xenia/cpu/hir/value.h @@ -385,7 +385,7 @@ class Value { bool Add(Value* other); bool Sub(Value* other); void Mul(Value* other); - void Div(Value* other); + void Div(Value* other, bool is_unsigned); static void MulAdd(Value* dest, Value* value1, Value* value2, Value* value3); static void MulSub(Value* dest, Value* value1, Value* value2, Value* value3); void Neg();