w6c+selfhost: cgen N_CAST signed narrow + peel !T on unsigned narrow

TY_RUNE excluded — wwstage primsize skips it; task #5 will collapse
both gates back to symmetric once type_isunsigned recurses TY_ENUM.
This commit is contained in:
2026-05-13 20:06:24 +09:00
parent 777c951fab
commit 388ab8a707
14 changed files with 421 additions and 32 deletions

View File

@@ -494,11 +494,41 @@ export fn encode(a: *asm_) i32 = {
emitmodrmmem(a, rcode(tt), p.from.reg, p.from.offset);
p = p.link; continue;
};};
if (isgpr(ft)) { if (isgpr(tt)) {
emitrex(a, rhi(tt), rhi(ft), 1);
emitbyte(a, 15u8);
emitbyte(a, 191u8); // 0xBF
emitbyte(a, modrmbyte(3, rcode(tt), rcode(ft)));
p = p.link; continue;
};};
os.write(2, "w6a: unsupported MOVSWQ shape\n".ptr, 29u64);
a.errs += 1;
p = p.link; continue;
};
if (op == A_MOVSBQ) {
// MOVSX r64, r/m8 — 0F BE /r with REX.W.
let ft: i32 = p.from.atype;
let tt: i32 = p.to.atype;
if (ft == D_INDIR) { if (isgpr(tt)) {
emitrex(a, rhi(tt), rhi(p.from.reg), 1);
emitbyte(a, 15u8);
emitbyte(a, 190u8); // 0xBE
emitmodrmmem(a, rcode(tt), p.from.reg, p.from.offset);
p = p.link; continue;
};};
if (isgpr(ft)) { if (isgpr(tt)) {
emitrex(a, rhi(tt), rhi(ft), 1);
emitbyte(a, 15u8);
emitbyte(a, 190u8); // 0xBE
emitbyte(a, modrmbyte(3, rcode(tt), rcode(ft)));
p = p.link; continue;
};};
os.write(2, "w6a: unsupported MOVSBQ shape\n".ptr, 29u64);
a.errs += 1;
p = p.link; continue;
};
if (op == A_MOVZBQ) {
let ft: i32 = p.from.atype;
let tt: i32 = p.to.atype;
@@ -549,6 +579,12 @@ export fn encode(a: *asm_) i32 = {
emitmodrmmem(a, rcode(tt), p.from.reg, p.from.offset);
p = p.link; continue;
};};
if (isgpr(ft)) { if (isgpr(tt)) {
emitrex(a, rhi(tt), rhi(ft), 1);
emitbyte(a, 99u8); // 0x63
emitbyte(a, modrmbyte(3, rcode(tt), rcode(ft)));
p = p.link; continue;
};};
os.write(2, "w6a: unsupported MOVSXD shape\n".ptr, 29u64);
a.errs += 1;
p = p.link; continue;

View File

@@ -421,6 +421,7 @@ def A_MOVSXD: i32 = 9;
def A_MOVW: i32 = 62;
def A_MOVZWQ: i32 = 63;
def A_MOVSWQ: i32 = 64;
def A_MOVSBQ: i32 = 65;
def A_MOVSD: i32 = 10;
def A_ADDSD: i32 = 11;
@@ -673,6 +674,7 @@ fn opcodelookup(p: *u8, n: u64) i32 = {
if (streqlit(p, n, "MOVZWQ")) { return A_MOVZWQ; };
if (streqlit(p, n, "MOVSXD")) { return A_MOVSXD; };
if (streqlit(p, n, "MOVSWQ")) { return A_MOVSWQ; };
if (streqlit(p, n, "MOVSBQ")) { return A_MOVSBQ; };
if (streqlit(p, n, "MOVSD")) { return A_MOVSD; };
if (streqlit(p, n, "ADDSD")) { return A_ADDSD; };
if (streqlit(p, n, "SUBSD")) { return A_SUBSD; };
@@ -1720,11 +1722,41 @@ export fn encode(a: *asm_) i32 = {
emitmodrmmem(a, rcode(tt), p.from.reg, p.from.offset);
p = p.link; continue;
};};
if (isgpr(ft)) { if (isgpr(tt)) {
emitrex(a, rhi(tt), rhi(ft), 1);
emitbyte(a, 15u8);
emitbyte(a, 191u8); // 0xBF
emitbyte(a, modrmbyte(3, rcode(tt), rcode(ft)));
p = p.link; continue;
};};
os.write(2, "w6a: unsupported MOVSWQ shape\n".ptr, 29u64);
a.errs += 1;
p = p.link; continue;
};
if (op == A_MOVSBQ) {
// MOVSX r64, r/m8 — 0F BE /r with REX.W.
let ft: i32 = p.from.atype;
let tt: i32 = p.to.atype;
if (ft == D_INDIR) { if (isgpr(tt)) {
emitrex(a, rhi(tt), rhi(p.from.reg), 1);
emitbyte(a, 15u8);
emitbyte(a, 190u8); // 0xBE
emitmodrmmem(a, rcode(tt), p.from.reg, p.from.offset);
p = p.link; continue;
};};
if (isgpr(ft)) { if (isgpr(tt)) {
emitrex(a, rhi(tt), rhi(ft), 1);
emitbyte(a, 15u8);
emitbyte(a, 190u8); // 0xBE
emitbyte(a, modrmbyte(3, rcode(tt), rcode(ft)));
p = p.link; continue;
};};
os.write(2, "w6a: unsupported MOVSBQ shape\n".ptr, 29u64);
a.errs += 1;
p = p.link; continue;
};
if (op == A_MOVZBQ) {
let ft: i32 = p.from.atype;
let tt: i32 = p.to.atype;
@@ -1775,6 +1807,12 @@ export fn encode(a: *asm_) i32 = {
emitmodrmmem(a, rcode(tt), p.from.reg, p.from.offset);
p = p.link; continue;
};};
if (isgpr(ft)) { if (isgpr(tt)) {
emitrex(a, rhi(tt), rhi(ft), 1);
emitbyte(a, 99u8); // 0x63
emitbyte(a, modrmbyte(3, rcode(tt), rcode(ft)));
p = p.link; continue;
};};
os.write(2, "w6a: unsupported MOVSXD shape\n".ptr, 29u64);
a.errs += 1;
p = p.link; continue;

View File

@@ -37,6 +37,7 @@ fn opcodelookup(p: *u8, n: u64) i32 = {
if (streqlit(p, n, "MOVZWQ")) { return A_MOVZWQ; };
if (streqlit(p, n, "MOVSXD")) { return A_MOVSXD; };
if (streqlit(p, n, "MOVSWQ")) { return A_MOVSWQ; };
if (streqlit(p, n, "MOVSBQ")) { return A_MOVSBQ; };
if (streqlit(p, n, "MOVSD")) { return A_MOVSD; };
if (streqlit(p, n, "ADDSD")) { return A_ADDSD; };
if (streqlit(p, n, "SUBSD")) { return A_SUBSD; };

View File

@@ -67,6 +67,7 @@ def A_MOVSXD: i32 = 9;
def A_MOVW: i32 = 62;
def A_MOVZWQ: i32 = 63;
def A_MOVSWQ: i32 = 64;
def A_MOVSBQ: i32 = 65;
def A_MOVSD: i32 = 10;
def A_ADDSD: i32 = 11;