Skip to content

Commit 2fdd04d

Browse files
authored
Merge pull request #55 from wokron/fix/mips
修正MIPS集成出错 (#53)
2 parents 51597e0 + 7f4ebda commit 2fdd04d

File tree

10 files changed

+77
-25
lines changed

10 files changed

+77
-25
lines changed

libs/mips/include/mips/mips_manager.h

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class MipsManager {
3131
ZeroReg *zero;
3232
StkPtrReg *sp;
3333
RetAddrReg *ra;
34+
ArgumentReg *a0;
3435
ValueReg *v0;
3536
// f0 和 f12 保留,用于输入输出
3637
FloatReg *f0;

libs/mips/src/mips_manager.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ MipsManager::MipsManager() {
1515
zero = new ZeroReg();
1616
sp = new StkPtrReg();
1717
ra = new RetAddrReg();
18+
a0 = new ArgumentReg(0);
1819
v0 = new ValueReg(0);
1920
f0 = new FloatReg(0);
2021
f12 = new FloatReg(12);
@@ -42,6 +43,7 @@ MipsManager::~MipsManager() {
4243
delete zero;
4344
delete sp;
4445
delete ra;
46+
delete a0;
4547
delete v0;
4648
delete f0;
4749
delete f12;

libs/mips/src/mips_printer.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ void ICode::PrintCode(std::ostream &out) {
160160
rs->PrintReg(out);
161161
out << ", " << label << std::endl;
162162
} else if (op <= BC1T && op >= BC1F) {
163-
Ope = op == BC1F ? "bc1f" : op == BC1T ? "bc1f" : "";
163+
Ope = op == BC1F ? "bc1f" : op == BC1T ? "bc1t" : "";
164164
out << Ope << " " << label << std::endl;
165165
} else {
166166
TOLANG_DIE("ICode not supported.");

libs/mips/src/translator.cpp

+23-8
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,17 @@ void Translator::translate(UnaryOperatorPtr unaryOperatorPtr) {
133133
manager->occupy(operandRegPtr, unaryOperatorPtr);
134134
} else if (unaryOperatorPtr->OpType() == UnaryOpType::Neg) { // -
135135
auto result = manager->allocReg(unaryOperatorPtr);
136+
if (unaryOperatorPtr->GetType()->IsIntegerTy()) {
137+
manager->addCode(
138+
new RCode(Subu, result, manager->zero, operandRegPtr));
139+
} else if (unaryOperatorPtr->GetType()->IsIntegerTy()) {
140+
auto reg0 = manager->getFreeFloat();
141+
std::string name0 = manager->addFloat(0);
142+
manager->addCode(new ICode(LS, reg0, name0));
143+
manager->addCode(new RCode(SubS, result, reg0, operandRegPtr));
144+
}
136145
auto optype = unaryOperatorPtr->GetType()->IsFloatTy() ? SubS : Subu;
137-
manager->addCode(
138-
new RCode(optype, result, manager->zero, operandRegPtr));
146+
139147
} else { // not !
140148
assert(unaryOperatorPtr->OpType() == UnaryOpType::Not &&
141149
"invalid unary operator");
@@ -211,11 +219,11 @@ void Translator::translate(CompareInstructionPtr compareInstructionPtr) {
211219
doOpposite = true;
212220
break;
213221
case CompareOpType::GreaterThan:
214-
op = CLtS;
222+
op = CLeS;
215223
doOpposite = true;
216224
break;
217225
case CompareOpType::GreaterThanOrEqual:
218-
op = CLeS;
226+
op = CLtS;
219227
doOpposite = true;
220228
break;
221229
case CompareOpType::LessThan:
@@ -255,10 +263,10 @@ void Translator::translate(BranchInstPtr branchInstPtr) {
255263
std::string falseLabel =
256264
*manager->getLabelName(branchInstPtr->FalseBlock());
257265

258-
manager->addCode(new ICode(Bnez, cond, falseLabel));
266+
manager->addCode(new ICode(Bnez, cond, trueLabel));
259267
manager->addCode(new RCode(Nop));
260268

261-
manager->addCode(new JCode(J, trueLabel));
269+
manager->addCode(new JCode(J, falseLabel));
262270
manager->addCode(new RCode(Nop));
263271
}
264272

@@ -269,8 +277,12 @@ void Translator::translate(CallInstPtr callInstPtr) {
269277
pushSet.insert(occ.first);
270278
}
271279
}
280+
for (UsePtr use : *(callInstPtr->GetUseList())) {
281+
pushSet.erase(use->GetValue());
282+
}
283+
272284
int pos = manager->currentOffset - 4 -
273-
4 * (pushSet.size() - callInstPtr->GetUseList()->size());
285+
4 * pushSet.size();
274286
for (UsePtr use : *(callInstPtr->GetUseList())) {
275287
MipsCodeType codeType =
276288
use->GetValue()->GetType()->IsFloatTy() ? SS : SW;
@@ -279,7 +291,6 @@ void Translator::translate(CallInstPtr callInstPtr) {
279291
use->GetValue()->GetType()->IsFloatTy() ? FloatRegTy : TmpRegTy);
280292
manager->addCode(new ICode(codeType, reg, manager->sp, pos));
281293
pos -= 4;
282-
pushSet.erase(use->GetValue());
283294
}
284295

285296
for (auto valuePtr : pushSet) {
@@ -405,4 +416,8 @@ void Translator::translate(OutputInstPtr outputInstPtr) {
405416
manager->addCode(new RCode(AddS, manager->f12, reg, reg0));
406417
manager->addCode(new ICode(Addiu, manager->v0, manager->zero, 2));
407418
manager->addCode(new RCode(Syscall));
419+
// for test: put '\n'
420+
manager->addCode(new ICode(Addiu, manager->a0, manager->zero, 10));
421+
manager->addCode(new ICode(Addiu, manager->v0, manager->zero, 11));
422+
manager->addCode(new RCode(Syscall));
408423
}

scripts/test.py

+26-8
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,36 @@ def general_test(test_files: list[pathlib.Path], preprocess_fn, run_fn, compare_
7979

8080

8181
def compare(test_result_file: pathlib.Path, output_file: pathlib.Path):
82+
83+
def is_not_empty_line(text: str):
84+
return len(text.strip()) > 0
85+
86+
def convert_to_float(text: str):
87+
try:
88+
val = float(text)
89+
except ValueError:
90+
print(f"line {no + 1}: {text} is not float")
91+
val = f"'{text}'"
92+
return val
93+
8294
with open(test_result_file, "r") as f:
83-
test_results = map(float, f.readlines())
95+
test_results = map(convert_to_float, filter(is_not_empty_line, f.readlines()))
8496
with open(output_file, "r") as f:
85-
expected_results = map(float, f.readlines())
97+
expected_results = map(
98+
convert_to_float, filter(is_not_empty_line, f.readlines())
99+
)
86100

87101
is_success = True
88-
for no, (test_result, expected_result) in enumerate(
89-
zip(test_results, expected_results)
90-
):
91-
if test_result != expected_result:
92-
is_success = False
93-
print(f"line {no + 1}: {test_result} != {expected_result}")
102+
try:
103+
for no, (test_result, expected_result) in enumerate(
104+
zip(test_results, expected_results, strict=True)
105+
):
106+
if type(test_result) != float or abs(test_result - expected_result) > 1e-6:
107+
is_success = False
108+
print(f"line {no + 1}: {test_result} != {expected_result}")
109+
except ValueError:
110+
is_success = False
111+
print("result number not matched")
94112

95113
return is_success
96114

testcases/fibo.input

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
3
44
5
55
7
6-
9
6+
9

testcases/newton.input

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
5
22
0.00001
3-
2 3 4 5 7
3+
2
4+
3
5+
4
6+
5
7+
7

testcases/sum.input

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,11 @@
11
10
2-
1 2 3 4 5 6 7 8 9 10
2+
1
3+
2
4+
3
5+
4
6+
5
7+
6
8+
7
9+
8
10+
9
11+
10

testcases/sum.output

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
55
1+
55

tests/test_mips.cpp

+7-4
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ add.s $f8, $f0, $f9
124124
s.s $f8, 0($sp)
125125
l.s $f10, 0($sp)
126126
l.s $f11, flt4
127-
c.lt.s $f10, $f11
127+
c.le.s $f10, $f11
128128
bc1f main_1
129129
nop
130130
addiu $t0, $zero, 0
@@ -135,9 +135,9 @@ nop
135135
addiu $t0, $zero, 1
136136
137137
main_2:
138-
bnez $t0, main_4
138+
bnez $t0, main_3
139139
nop
140-
j main_3
140+
j main_4
141141
nop
142142
143143
main_3:
@@ -146,6 +146,9 @@ l.s $f14, flt1
146146
add.s $f12, $f13, $f14
147147
addiu $v0, $zero, 2
148148
syscall
149+
addiu $a0, $zero, 10
150+
addiu $v0, $zero, 11
151+
syscall
149152
j main_5
150153
nop
151154
@@ -177,7 +180,7 @@ TEST_CASE("testing mips") {
177180
translator.print(ss);
178181

179182
auto ir = ss.str();
180-
// std::cout << ir;
183+
// std::cout << ir;
181184
CHECK_EQ(ir, EXPECTED);
182185
}
183186

0 commit comments

Comments
 (0)