diff --git a/libs/mips/include/mips/mips_manager.h b/libs/mips/include/mips/mips_manager.h index 8413eb0..f18c33f 100644 --- a/libs/mips/include/mips/mips_manager.h +++ b/libs/mips/include/mips/mips_manager.h @@ -31,6 +31,7 @@ class MipsManager { ZeroReg *zero; StkPtrReg *sp; RetAddrReg *ra; + ArgumentReg *a0; ValueReg *v0; // f0 和 f12 保留,用于输入输出 FloatReg *f0; diff --git a/libs/mips/src/mips_manager.cpp b/libs/mips/src/mips_manager.cpp index 10fba36..01ba060 100644 --- a/libs/mips/src/mips_manager.cpp +++ b/libs/mips/src/mips_manager.cpp @@ -15,6 +15,7 @@ MipsManager::MipsManager() { zero = new ZeroReg(); sp = new StkPtrReg(); ra = new RetAddrReg(); + a0 = new ArgumentReg(0); v0 = new ValueReg(0); f0 = new FloatReg(0); f12 = new FloatReg(12); @@ -42,6 +43,7 @@ MipsManager::~MipsManager() { delete zero; delete sp; delete ra; + delete a0; delete v0; delete f0; delete f12; diff --git a/libs/mips/src/mips_printer.cpp b/libs/mips/src/mips_printer.cpp index dc45064..652cc09 100644 --- a/libs/mips/src/mips_printer.cpp +++ b/libs/mips/src/mips_printer.cpp @@ -160,7 +160,7 @@ void ICode::PrintCode(std::ostream &out) { rs->PrintReg(out); out << ", " << label << std::endl; } else if (op <= BC1T && op >= BC1F) { - Ope = op == BC1F ? "bc1f" : op == BC1T ? "bc1f" : ""; + Ope = op == BC1F ? "bc1f" : op == BC1T ? "bc1t" : ""; out << Ope << " " << label << std::endl; } else { TOLANG_DIE("ICode not supported."); diff --git a/libs/mips/src/translator.cpp b/libs/mips/src/translator.cpp index 5d2c1fb..ecd2f2b 100644 --- a/libs/mips/src/translator.cpp +++ b/libs/mips/src/translator.cpp @@ -133,9 +133,17 @@ void Translator::translate(UnaryOperatorPtr unaryOperatorPtr) { manager->occupy(operandRegPtr, unaryOperatorPtr); } else if (unaryOperatorPtr->OpType() == UnaryOpType::Neg) { // - auto result = manager->allocReg(unaryOperatorPtr); + if (unaryOperatorPtr->GetType()->IsIntegerTy()) { + manager->addCode( + new RCode(Subu, result, manager->zero, operandRegPtr)); + } else if (unaryOperatorPtr->GetType()->IsIntegerTy()) { + auto reg0 = manager->getFreeFloat(); + std::string name0 = manager->addFloat(0); + manager->addCode(new ICode(LS, reg0, name0)); + manager->addCode(new RCode(SubS, result, reg0, operandRegPtr)); + } auto optype = unaryOperatorPtr->GetType()->IsFloatTy() ? SubS : Subu; - manager->addCode( - new RCode(optype, result, manager->zero, operandRegPtr)); + } else { // not ! assert(unaryOperatorPtr->OpType() == UnaryOpType::Not && "invalid unary operator"); @@ -211,11 +219,11 @@ void Translator::translate(CompareInstructionPtr compareInstructionPtr) { doOpposite = true; break; case CompareOpType::GreaterThan: - op = CLtS; + op = CLeS; doOpposite = true; break; case CompareOpType::GreaterThanOrEqual: - op = CLeS; + op = CLtS; doOpposite = true; break; case CompareOpType::LessThan: @@ -255,10 +263,10 @@ void Translator::translate(BranchInstPtr branchInstPtr) { std::string falseLabel = *manager->getLabelName(branchInstPtr->FalseBlock()); - manager->addCode(new ICode(Bnez, cond, falseLabel)); + manager->addCode(new ICode(Bnez, cond, trueLabel)); manager->addCode(new RCode(Nop)); - manager->addCode(new JCode(J, trueLabel)); + manager->addCode(new JCode(J, falseLabel)); manager->addCode(new RCode(Nop)); } @@ -269,8 +277,12 @@ void Translator::translate(CallInstPtr callInstPtr) { pushSet.insert(occ.first); } } + for (UsePtr use : *(callInstPtr->GetUseList())) { + pushSet.erase(use->GetValue()); + } + int pos = manager->currentOffset - 4 - - 4 * (pushSet.size() - callInstPtr->GetUseList()->size()); + 4 * pushSet.size(); for (UsePtr use : *(callInstPtr->GetUseList())) { MipsCodeType codeType = use->GetValue()->GetType()->IsFloatTy() ? SS : SW; @@ -279,7 +291,6 @@ void Translator::translate(CallInstPtr callInstPtr) { use->GetValue()->GetType()->IsFloatTy() ? FloatRegTy : TmpRegTy); manager->addCode(new ICode(codeType, reg, manager->sp, pos)); pos -= 4; - pushSet.erase(use->GetValue()); } for (auto valuePtr : pushSet) { @@ -405,4 +416,8 @@ void Translator::translate(OutputInstPtr outputInstPtr) { manager->addCode(new RCode(AddS, manager->f12, reg, reg0)); manager->addCode(new ICode(Addiu, manager->v0, manager->zero, 2)); manager->addCode(new RCode(Syscall)); + // for test: put '\n' + manager->addCode(new ICode(Addiu, manager->a0, manager->zero, 10)); + manager->addCode(new ICode(Addiu, manager->v0, manager->zero, 11)); + manager->addCode(new RCode(Syscall)); } diff --git a/scripts/test.py b/scripts/test.py index 87f215b..a59f74b 100644 --- a/scripts/test.py +++ b/scripts/test.py @@ -79,18 +79,36 @@ def general_test(test_files: list[pathlib.Path], preprocess_fn, run_fn, compare_ def compare(test_result_file: pathlib.Path, output_file: pathlib.Path): + + def is_not_empty_line(text: str): + return len(text.strip()) > 0 + + def convert_to_float(text: str): + try: + val = float(text) + except ValueError: + print(f"line {no + 1}: {text} is not float") + val = f"'{text}'" + return val + with open(test_result_file, "r") as f: - test_results = map(float, f.readlines()) + test_results = map(convert_to_float, filter(is_not_empty_line, f.readlines())) with open(output_file, "r") as f: - expected_results = map(float, f.readlines()) + expected_results = map( + convert_to_float, filter(is_not_empty_line, f.readlines()) + ) is_success = True - for no, (test_result, expected_result) in enumerate( - zip(test_results, expected_results) - ): - if test_result != expected_result: - is_success = False - print(f"line {no + 1}: {test_result} != {expected_result}") + try: + for no, (test_result, expected_result) in enumerate( + zip(test_results, expected_results, strict=True) + ): + if type(test_result) != float or abs(test_result - expected_result) > 1e-6: + is_success = False + print(f"line {no + 1}: {test_result} != {expected_result}") + except ValueError: + is_success = False + print("result number not matched") return is_success diff --git a/testcases/fibo.input b/testcases/fibo.input index 88e0b7e..4896dee 100644 --- a/testcases/fibo.input +++ b/testcases/fibo.input @@ -3,4 +3,4 @@ 3 5 7 -9 +9 \ No newline at end of file diff --git a/testcases/newton.input b/testcases/newton.input index b3b5ced..c387dc8 100644 --- a/testcases/newton.input +++ b/testcases/newton.input @@ -1,3 +1,7 @@ 5 0.00001 -2 3 4 5 7 +2 +3 +4 +5 +7 diff --git a/testcases/sum.input b/testcases/sum.input index 63bb245..c59d0b3 100644 --- a/testcases/sum.input +++ b/testcases/sum.input @@ -1,2 +1,11 @@ 10 -1 2 3 4 5 6 7 8 9 10 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 \ No newline at end of file diff --git a/testcases/sum.output b/testcases/sum.output index c3f407c..7c6ba0f 100644 --- a/testcases/sum.output +++ b/testcases/sum.output @@ -1 +1 @@ -55 +55 \ No newline at end of file diff --git a/tests/test_mips.cpp b/tests/test_mips.cpp index b3cec74..677789b 100644 --- a/tests/test_mips.cpp +++ b/tests/test_mips.cpp @@ -124,7 +124,7 @@ add.s $f8, $f0, $f9 s.s $f8, 0($sp) l.s $f10, 0($sp) l.s $f11, flt4 -c.lt.s $f10, $f11 +c.le.s $f10, $f11 bc1f main_1 nop addiu $t0, $zero, 0 @@ -135,9 +135,9 @@ nop addiu $t0, $zero, 1 main_2: -bnez $t0, main_4 +bnez $t0, main_3 nop -j main_3 +j main_4 nop main_3: @@ -146,6 +146,9 @@ l.s $f14, flt1 add.s $f12, $f13, $f14 addiu $v0, $zero, 2 syscall +addiu $a0, $zero, 10 +addiu $v0, $zero, 11 +syscall j main_5 nop @@ -177,7 +180,7 @@ TEST_CASE("testing mips") { translator.print(ss); auto ir = ss.str(); - // std::cout << ir; +// std::cout << ir; CHECK_EQ(ir, EXPECTED); }