步骤A:isa+toml 新增 RS_OFF 形态(LOAD_PTR/STORE_PTR,0010 前缀 op=8/9)+ 强校验放行 + isa_test roundtrip
This commit is contained in:
@@ -669,6 +669,24 @@ func = "full"
|
||||
params = ["slot", "off", "rs"]
|
||||
enabled = true
|
||||
|
||||
[[op]]
|
||||
name = "LOAD_PTR"
|
||||
prefix = "0010"
|
||||
op = 8
|
||||
fmt = "RS+off"
|
||||
func = "full"
|
||||
params = ["rd", "rs", "off"]
|
||||
enabled = true
|
||||
|
||||
[[op]]
|
||||
name = "STORE_PTR"
|
||||
prefix = "0010"
|
||||
op = 9
|
||||
fmt = "RS+off"
|
||||
func = "full"
|
||||
params = ["rd", "rs", "off"]
|
||||
enabled = true
|
||||
|
||||
[[op]]
|
||||
name = "STR_LEN"
|
||||
prefix = "0010"
|
||||
|
||||
@@ -89,6 +89,7 @@ namespace {
|
||||
if (fmt == "CALL") return 1;
|
||||
if (fmt == "CAL") return 2;
|
||||
if (fmt == "SLOT+off") return 3;
|
||||
if (fmt == "RS+off") return 3;
|
||||
if (fmt == "IMM64") return 2;
|
||||
if (fmt == "预留") return 0;
|
||||
return -1;
|
||||
@@ -132,7 +133,7 @@ namespace {
|
||||
if (prefix == "010011") return "JC";
|
||||
if (prefix == "010100") return "CALL";
|
||||
if (prefix == "010101") return "CAL";
|
||||
if (prefix == "0010") return "SLOT+off";
|
||||
if (prefix == "0010") return "SLOT+off"; // 或 RS+off(LOAD_PTR/STORE_PTR)
|
||||
if (prefix == "0011") return "IMM64";
|
||||
if (prefix == "0001") return "预留";
|
||||
return "";
|
||||
@@ -392,9 +393,12 @@ bool MachineConfig::load(const std::string& path, std::string* err) {
|
||||
fail(err, "op '" + op.name + "': bad prefix '" + op.prefix + "'");
|
||||
return false;
|
||||
}
|
||||
// prefix ↔ fmt 互锁
|
||||
// prefix ↔ fmt 互锁(0010 允许 SLOT+off 与 RS+off 两种形态)
|
||||
const char* want_fmt = fmt_of_prefix(op.prefix);
|
||||
if (want_fmt == nullptr || op.fmt != want_fmt) {
|
||||
const bool ok_fmt =
|
||||
op.fmt == want_fmt ||
|
||||
(op.prefix == "0010" && op.fmt == "RS+off");
|
||||
if (!ok_fmt) {
|
||||
fail(err, "op '" + op.name + "': prefix '" + op.prefix +
|
||||
"' must pair with fmt '" + std::string(want_fmt ? want_fmt : "?") + "'");
|
||||
return false;
|
||||
|
||||
@@ -295,6 +295,17 @@ namespace isa {
|
||||
return instr_len(out);
|
||||
}
|
||||
|
||||
/// @brief 编码 RS_OFF(LOAD_PTR/STORE_PTR,0010 区),返回指令长度。
|
||||
inline size_t enc_rs_off(uint8_t* out, uint8_t op, uint8_t func,
|
||||
uint8_t rd, uint8_t rs, int32_t off) {
|
||||
set_byte0(out, "0010", op);
|
||||
set_func(out, func);
|
||||
set_rd(out, rd);
|
||||
set_rs1(out, rs);
|
||||
set_off32_hi(out, off);
|
||||
return instr_len(out);
|
||||
}
|
||||
|
||||
/// @brief 编码 RET(10 区),返回指令长度。
|
||||
inline size_t enc_ret(uint8_t* out) {
|
||||
set_byte0(out, "10", static_cast<uint8_t>(Op::RET));
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace isa {
|
||||
// 16B(前缀 0010/0011,op 4 位)
|
||||
LOAD_OFF = 0, STORE_OFF = 1, STR_LEN = 2, STR_CMP = 3,
|
||||
STR_EQ = 4, STR_MID = 5, STR_LEFT = 6, STR_RIGHT = 7,
|
||||
LOAD_PTR = 8, STORE_PTR = 9,
|
||||
LOADK64 = 0,
|
||||
// 32B 预留(前缀 0001,op 4 位)
|
||||
JTBL = 0, STR_CONCAT = 1, STR_FIND = 2, STR_REPLACE = 3,
|
||||
@@ -66,6 +67,7 @@ namespace isa {
|
||||
CALL, ///< fn_id32(8B)
|
||||
CAL, ///< fb_id16, slot32(8B)
|
||||
SLOT_OFF, ///< rd, slot32, off32(16B)
|
||||
RS_OFF, ///< rd, rs(基址寄存器), off32(16B)
|
||||
IMM64, ///< rd, imm64(16B)
|
||||
RESERVED, ///< 32B 预留
|
||||
};
|
||||
|
||||
@@ -84,6 +84,8 @@ Decoded decode(const uint8_t* code, size_t len) {
|
||||
} else if (f == OpFormat::SLOT_OFF) {
|
||||
d.imm32 = slot32_of(code);
|
||||
d.off_hi = off32_hi_of(code);
|
||||
} else if (f == OpFormat::RS_OFF) {
|
||||
d.off_hi = off32_hi_of(code);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
@@ -112,6 +114,8 @@ size_t encode(const Decoded& d, uint8_t* out) {
|
||||
} else if (f == OpFormat::SLOT_OFF) {
|
||||
set_slot32(out, d.imm32);
|
||||
set_off32_hi(out, d.off_hi);
|
||||
} else if (f == OpFormat::RS_OFF) {
|
||||
set_off32_hi(out, d.off_hi);
|
||||
}
|
||||
return instr_len(out);
|
||||
}
|
||||
@@ -178,6 +182,11 @@ void disasm(const uint8_t* code, size_t len, char* out, size_t cap) {
|
||||
static_cast<unsigned>(d.rd), static_cast<unsigned>(d.imm32),
|
||||
static_cast<int>(d.off_hi));
|
||||
break;
|
||||
case OpFormat::RS_OFF:
|
||||
snprintf(out, cap, "%s%s r%u, r%u, %d", od.name, suffix.c_str(),
|
||||
static_cast<unsigned>(d.rd), static_cast<unsigned>(d.rs1),
|
||||
static_cast<int>(d.off_hi));
|
||||
break;
|
||||
case OpFormat::IMM64:
|
||||
case OpFormat::NONE:
|
||||
case OpFormat::RESERVED:
|
||||
|
||||
+4
-2
@@ -88,6 +88,8 @@ namespace isa {
|
||||
{"STR_MID", "0010", Op::STR_MID, OpFormat::SLOT_OFF, FuncMode::None},
|
||||
{"STR_LEFT", "0010", Op::STR_LEFT, OpFormat::SLOT_OFF, FuncMode::None},
|
||||
{"STR_RIGHT", "0010", Op::STR_RIGHT, OpFormat::SLOT_OFF, FuncMode::None},
|
||||
{"LOAD_PTR", "0010", Op::LOAD_PTR, OpFormat::RS_OFF, FuncMode::Full},
|
||||
{"STORE_PTR", "0010", Op::STORE_PTR, OpFormat::RS_OFF, FuncMode::Full},
|
||||
{"LOADK64", "0011", Op::LOADK64, OpFormat::IMM64, FuncMode::Full},
|
||||
// 32B 预留
|
||||
{"JTBL", "0001", Op::JTBL, OpFormat::RESERVED, FuncMode::None},
|
||||
@@ -144,11 +146,11 @@ namespace isa {
|
||||
bool uses_rd(OpFormat f) {
|
||||
return f == OpFormat::RR || f == OpFormat::RRR || f == OpFormat::IMM ||
|
||||
f == OpFormat::SLOT || f == OpFormat::JC || f == OpFormat::SLOT_OFF ||
|
||||
f == OpFormat::IMM64;
|
||||
f == OpFormat::RS_OFF || f == OpFormat::IMM64;
|
||||
}
|
||||
|
||||
bool uses_rs1(OpFormat f) {
|
||||
return f == OpFormat::RR || f == OpFormat::RRR;
|
||||
return f == OpFormat::RR || f == OpFormat::RRR || f == OpFormat::RS_OFF;
|
||||
}
|
||||
|
||||
bool uses_rs2(OpFormat f) {
|
||||
|
||||
@@ -128,6 +128,11 @@ static bool test_fields() {
|
||||
enc_slot_off(buf, static_cast<uint8_t>(isa::Op::LOAD_OFF), 3, 1, 9, -12);
|
||||
CHECK(slot32_of(buf) == 9);
|
||||
CHECK(off32_hi_of(buf) == -12);
|
||||
// RS_OFF(0010 op=8/9:rd@2、rs1@3、off@87..56)
|
||||
enc_rs_off(buf, static_cast<uint8_t>(isa::Op::LOAD_PTR), 3, 5, 1, -12);
|
||||
CHECK(rd_of(buf) == 5);
|
||||
CHECK(rs1_of(buf) == 1);
|
||||
CHECK(off32_hi_of(buf) == -12);
|
||||
// RET
|
||||
enc_ret(buf);
|
||||
CHECK(op_of(buf) == static_cast<uint8_t>(isa::Op::RET));
|
||||
@@ -197,6 +202,20 @@ static bool test_disasm() {
|
||||
enc_slot_off(buf, static_cast<uint8_t>(isa::Op::LOAD_OFF), 3, 2, 8, 16);
|
||||
isa::disasm(buf, 16, out, sizeof out);
|
||||
CHECK(std::strcmp(out, "LOAD_OFF.I16 r2, s8, 16") == 0);
|
||||
// RS_OFF(LOAD_PTR/STORE_PTR)
|
||||
enc_rs_off(buf, static_cast<uint8_t>(isa::Op::LOAD_PTR), 3, 2, 1, 16);
|
||||
isa::disasm(buf, 16, out, sizeof out);
|
||||
CHECK(std::strcmp(out, "LOAD_PTR.I16 r2, r1, 16") == 0);
|
||||
enc_rs_off(buf, static_cast<uint8_t>(isa::Op::STORE_PTR), 9, 9, 1, -4);
|
||||
isa::disasm(buf, 16, out, sizeof out);
|
||||
CHECK(std::strcmp(out, "STORE_PTR.F64 r9, r1, -4") == 0);
|
||||
// decode 回读(encode 路径)
|
||||
{
|
||||
isa::Decoded d = isa::decode(buf, 16);
|
||||
isa::encode(d, buf);
|
||||
isa::disasm(buf, 16, out, sizeof out);
|
||||
CHECK(std::strcmp(out, "STORE_PTR.F64 r9, r1, -4") == 0);
|
||||
}
|
||||
// 未知(010110 预留区)
|
||||
buf[0] = 0x58;
|
||||
isa::disasm(buf, 8, out, sizeof out);
|
||||
|
||||
@@ -132,7 +132,7 @@ static bool test_positive() {
|
||||
CHECK(cfg.find_type("DT") != nullptr && cfg.find_type("DT")->func == 6);
|
||||
CHECK(cfg.find_type("NOPE") == nullptr);
|
||||
|
||||
CHECK(cfg.ops().size() == 72);
|
||||
CHECK(cfg.ops().size() == 74);
|
||||
const compiler::ConfigOp* move = cfg.find_op("MOVE");
|
||||
CHECK(move != nullptr && move->prefix == "11" && move->op == 0 && move->fmt == "RR" &&
|
||||
move->func_mode == "width" && move->params.size() == 2);
|
||||
|
||||
Reference in New Issue
Block a user