fix(includes): asm 内联汇编输出占位符/clobber、vipermath 位重解释、string.split 容量参数
- asm.vp: inb/inw/inl 模板引用输出占位符 \ 并补 ~{rax}(原取硬编码 eax 且静默破坏 EAX,对齐 mm.vp cmos_read 模式)
- vipermath.vp: isnan/isinf 改 c.Load 位重解释(原 fptosi 位模式丢失导致恒返回 0)
- string.vp: split 增加 cap 容量参数,token 数 <= cap-1,防止越界写
This commit is contained in:
1 parent
728d090815
commit
52af24e85d
3 files changed
+37
-13
No files matched your search
@@ -18,11 +18,14 @@ def pause():
|
||||
|
||||
def inb(port: t.CUInt16T) -> t.CUInt8T:
|
||||
value: t.CUInt32T
|
||||
# 模板内必须引用输出占位符 $0(DSL 约定,见 atom.vp),否则输出寄存器由 LLVM
|
||||
# 任意分配而结果取自硬编码 eax → 读到未定义寄存器;同时 in al,dx 改写 AL,
|
||||
# 需显式声明 ~{rax} clobber。
|
||||
c.Asm(f"""mov edx, {c.AsmInp(t.CUInt32T(port), t.ASM_DESCR.REG_ANY)}
|
||||
in al, dx
|
||||
movzx eax, al""",
|
||||
movzx $0, al""",
|
||||
out = [c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)],
|
||||
op =[t.ASM_DESCR.CLOBBER_RDX])
|
||||
op =[t.ASM_DESCR.CLOBBER_RDX, t.ASM_DESCR.CLOBBER_RAX])
|
||||
return t.CUInt8T(value)
|
||||
|
||||
def outb(port: t.CUInt16T, value: t.CUInt8T):
|
||||
@@ -36,9 +39,10 @@ def inw(port: t.CUInt16T) -> t.CUInt16T:
|
||||
value: t.CUInt32T
|
||||
c.Asm(f"""mov edx, {c.AsmInp(t.CUInt32T(port), t.ASM_DESCR.REG_ANY)}
|
||||
in ax, dx
|
||||
movzx eax, ax""",
|
||||
movzx eax, ax
|
||||
mov {c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)}, eax""",
|
||||
out = [c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)],
|
||||
op =[t.ASM_DESCR.CLOBBER_RDX])
|
||||
op =[t.ASM_DESCR.CLOBBER_RDX, t.ASM_DESCR.CLOBBER_RAX])
|
||||
return t.CUInt16T(value)
|
||||
|
||||
def outw(port: t.CUInt16T, value: t.CUInt16T):
|
||||
@@ -50,9 +54,10 @@ def outw(port: t.CUInt16T, value: t.CUInt16T):
|
||||
def inl(port: t.CUInt16T) -> t.CUInt32T:
|
||||
value: t.CUInt32T
|
||||
c.Asm(f"""mov edx, {c.AsmInp(t.CUInt32T(port), t.ASM_DESCR.REG_ANY)}
|
||||
in eax, dx""",
|
||||
in eax, dx
|
||||
mov {c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)}, eax""",
|
||||
out = [c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)],
|
||||
op =[t.ASM_DESCR.CLOBBER_RDX])
|
||||
op =[t.ASM_DESCR.CLOBBER_RDX, t.ASM_DESCR.CLOBBER_RAX])
|
||||
return value
|
||||
|
||||
def outl(port: t.CUInt16T, value: t.CUInt32T):
|
||||
|
||||
@@ -383,17 +383,29 @@ def atof_out(src: str, out: t.CDouble | t.CPtr) -> int:
|
||||
out[0] = v
|
||||
return 1
|
||||
|
||||
def split(s: str, delim: str, result: t.CArray[str]) -> int:
|
||||
def split(s: str, delim: str, result: t.CArray[str], cap: int) -> int:
|
||||
"""按单字符分隔符切分 s,token 指针写入 result[0..],尾部写 None 哨兵。
|
||||
|
||||
cap: result 数组的**声明容量**(元素个数)。此前无容量参数 → 写
|
||||
result[count] 与 result[count]=None 均无上界;token 数超过调用方数组
|
||||
容量时越界写(devfs 用 t.CArray[str, 256],256 个 token 即写穿 2048 字节)。
|
||||
现限制 token 数 ≤ cap-1(留一格给结尾哨兵)。
|
||||
"""
|
||||
count: int = 0
|
||||
start: str = s
|
||||
if not s or not delim or not result:
|
||||
return 0
|
||||
if cap <= 0:
|
||||
return 0
|
||||
d: t.CChar = delim[0] # 单分隔符
|
||||
|
||||
while start[0]:
|
||||
# 跳过分隔符
|
||||
while start[0] == d: start += 1
|
||||
if not start[0]: break
|
||||
# 容量保护:留最后一格放结尾哨兵
|
||||
if count >= cap - 1:
|
||||
break
|
||||
|
||||
# 记录token起始
|
||||
result[count] = start
|
||||
|
||||
+13
-6
@@ -526,7 +526,12 @@ class _U(t.CUnion):
|
||||
u: t.CUInt64T
|
||||
|
||||
def isnan(x: t.CDouble) -> t.CStatic | t.CInt:
|
||||
u: t.CUInt64T = t.CUInt64T(x)
|
||||
# IEEE-754 位重解释(不能用 t.CUInt64T(x) 数值转换:那是 fptosi,位模式全丢
|
||||
# → exp_part 恒 0 → 永远返回 0)。用 c.Load 按位拷贝(viperlib
|
||||
# _check_special_float 同款惯用法)。
|
||||
xv: t.CDouble = x
|
||||
u: t.CUInt64T = 0
|
||||
c.Load(c.Addr(u), c.Addr(xv))
|
||||
exp_part: t.CUInt64T = (u >> 52) & 0x7FF
|
||||
mantissa_part: t.CUInt64T = u & 0xFFFFFFFFFFFFF
|
||||
if exp_part == 0x7FF:
|
||||
@@ -535,10 +540,12 @@ def isnan(x: t.CDouble) -> t.CStatic | t.CInt:
|
||||
return 0
|
||||
|
||||
def isinf(x: t.CDouble) -> t.CStatic | t.CInt:
|
||||
u: t.CUInt64T = t.CUInt64T(x)
|
||||
exp_part: t.CUInt64T = (u >> 52) & 0x7FF
|
||||
mantissa_part: t.CUInt64T = u & 0xFFFFFFFFFFFFF
|
||||
if exp_part == 0x7FF:
|
||||
if mantissa_part == 0:
|
||||
xv2: t.CDouble = x
|
||||
u2: t.CUInt64T = 0
|
||||
c.Load(c.Addr(u2), c.Addr(xv2))
|
||||
exp_part2: t.CUInt64T = (u2 >> 52) & 0x7FF
|
||||
mantissa_part2: t.CUInt64T = u2 & 0xFFFFFFFFFFFFF
|
||||
if exp_part2 == 0x7FF:
|
||||
if mantissa_part2 == 0:
|
||||
return 1
|
||||
return 0
|
||||
Reference in new issue
Block a user