12.8 切片 3:NOT 与短路 AND/OR(编跳转)。
- 短路模式:<lhs→rd> JF(AND)/JT(OR) rd, L_end <rhs→t> MOVE rd, t L_end: - patch_jump 回填偏移;约定相对下一条指令(目标 = 当前 + 1 + off),冻结进 isa 规格 - codegen_test:71 断言(用例 03 跳转序列 JF/JT +2、NOT 序列),ctest 9/9
This commit is contained in:
@@ -279,6 +279,74 @@ static bool test_write_input() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---- 7. 用例 03:短路 AND / OR 必须编跳转 ----
|
||||
|
||||
static bool test_case03() {
|
||||
std::vector<uint8_t> img;
|
||||
std::string err;
|
||||
CHECK(compile_case("03_short_circuit", &img, &err));
|
||||
|
||||
const isa::ImageView v = isa::ImageView::from(img);
|
||||
CHECK(v.ok());
|
||||
const isa::FuncRow r = v.func_row(0);
|
||||
CHECK(r.nregs == 4); // a b x + 1 临时
|
||||
CHECK(r.code_len == 9);
|
||||
|
||||
char buf[64];
|
||||
const uint8_t* base = v.code_bytes();
|
||||
const uint32_t* ins = reinterpret_cast<const uint32_t*>(base);
|
||||
// x := a AND b:MOVE r2,r0 / JF r2,+2 / MOVE r3,r1 / MOVE r2,r3
|
||||
isa::disasm(ins[0], buf, sizeof buf);
|
||||
CHECK(std::strcmp(buf, "MOVE r2, r0") == 0);
|
||||
isa::disasm(ins[1], buf, sizeof buf);
|
||||
CHECK(std::strcmp(buf, "JF r2, +2") == 0);
|
||||
isa::disasm(ins[2], buf, sizeof buf);
|
||||
CHECK(std::strcmp(buf, "MOVE r3, r1") == 0);
|
||||
isa::disasm(ins[3], buf, sizeof buf);
|
||||
CHECK(std::strcmp(buf, "MOVE r2, r3") == 0);
|
||||
// x := a OR b:MOVE r2,r0 / JT r2,+2 / MOVE r3,r1 / MOVE r2,r3
|
||||
isa::disasm(ins[4], buf, sizeof buf);
|
||||
CHECK(std::strcmp(buf, "MOVE r2, r0") == 0);
|
||||
isa::disasm(ins[5], buf, sizeof buf);
|
||||
CHECK(std::strcmp(buf, "JT r2, +2") == 0);
|
||||
isa::disasm(ins[6], buf, sizeof buf);
|
||||
CHECK(std::strcmp(buf, "MOVE r3, r1") == 0);
|
||||
isa::disasm(ins[7], buf, sizeof buf);
|
||||
CHECK(std::strcmp(buf, "MOVE r2, r3") == 0);
|
||||
isa::disasm(ins[8], buf, sizeof buf);
|
||||
CHECK(std::strcmp(buf, "RET") == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---- 8. NOT ----
|
||||
|
||||
static bool test_not() {
|
||||
std::vector<uint8_t> img;
|
||||
std::string err;
|
||||
const char* main_st =
|
||||
"PROGRAM MAIN\nVAR\n a, x : BOOL;\nEND_VAR\n"
|
||||
" x := NOT a;\n"
|
||||
"END_PROGRAM\n";
|
||||
CHECK(compile_src("not", "", "", main_st, &img, &err));
|
||||
|
||||
const isa::ImageView v = isa::ImageView::from(img);
|
||||
CHECK(v.ok());
|
||||
const isa::FuncRow r = v.func_row(0);
|
||||
CHECK(r.nregs == 3); // a x + 1 临时
|
||||
CHECK(r.code_len == 3);
|
||||
|
||||
char buf[64];
|
||||
const uint8_t* base = v.code_bytes();
|
||||
const uint32_t* ins = reinterpret_cast<const uint32_t*>(base);
|
||||
isa::disasm(ins[0], buf, sizeof buf);
|
||||
CHECK(std::strcmp(buf, "MOVE r2, r0") == 0); // 临时 ← a
|
||||
isa::disasm(ins[1], buf, sizeof buf);
|
||||
CHECK(std::strcmp(buf, "NOT r1, r2") == 0); // x := NOT 临时
|
||||
isa::disasm(ins[2], buf, sizeof buf);
|
||||
CHECK(std::strcmp(buf, "RET") == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
int main() {
|
||||
if (!test_case01()) return 1;
|
||||
if (!test_case02()) return 1;
|
||||
@@ -286,6 +354,8 @@ int main() {
|
||||
if (!test_io_ops()) return 1;
|
||||
if (!test_layout()) return 1;
|
||||
if (!test_write_input()) return 1;
|
||||
if (!test_case03()) return 1;
|
||||
if (!test_not()) return 1;
|
||||
std::printf("codegen_test: %d checks passed\n", g_checks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user