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:
2026-08-21 11:40:53 +08:00
parent ac411e6a4a
commit e7dee50cde
3 changed files with 126 additions and 17 deletions
+70
View File
@@ -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 bMOVE 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 bMOVE 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;
}