6c: float compare, fn-address @symbol, indirect call

Three N_BIN/N_IDENT/N_CALL sites missed cases that bit ncurses
demos and dyn-linker exercises:

- Float compare emitted CMPQ + signed Jcc on f64 bits. Now goes
  through UCOMISD/UCOMISS + the unsigned Jcc family, mirroring
  Plan 9 6c (txt.c around AUCOMISD).
- LEAQ-of-fn-ident (taking the address of a function as a value)
  used n->str without ffi_resolve, so binding a *fn from an
  @symbol("name") fn declaration produced a reference to the
  ww ident rather than the C symbol.
- N_CALL on a bare ident with no localfind hit was a direct
  CALL ident(SB). Now checks localfind first and indirects
  through AX when the callee names a local fn-pointer slot.

Hare/QBE handles both shapes the same way (sort/search.ha:15
calls cmp(...) where cmp is a *cmpfunc parameter).
This commit is contained in:
2026-05-11 09:42:02 +09:00
parent cb57cd795d
commit 635818eb13
2 changed files with 88 additions and 3 deletions

View File

@@ -62,6 +62,26 @@ static const struct row rows[] = {
/* float: arg, arith, literal, cast back to int */
{ "fn area(r: f64) f64 = { return 3.14 * r * r; };\n"
"fn main() i32 = { let a: f64 = area(5.0); return a: i32; };", 78 },
/* float comparison: must emit UCOMISD + JA (not CMPQ + JG) */
{ "fn main() i32 = {\n"
" let a: f64 = 1.5;\n"
" let b: f64 = 2.5;\n"
" if (a < b) { if (b > a) { return 7; }; };\n"
" return 0;\n"
"};", 7 },
/* float ==/!= via UCOMISD */
{ "fn main() i32 = {\n"
" let a: f64 = 3.14;\n"
" let b: f64 = 3.14;\n"
" if (a == b) { return 11; };\n"
" return 0;\n"
"};", 11 },
/* function pointer: take address of a named fn, call indirectly */
{ "fn add(a: i32, b: i32) i32 = { return a + b; };\n"
"fn main() i32 = {\n"
" let fp: fn(a: i32, b: i32) i32 = add;\n"
" return fp(20, 22);\n"
"};", 42 },
/* string literal via syscall — exit code = bytes written */
{ "@symbol(\"rt_syscall\") fn rt_syscall(num: i64, a: i64, b: i64, c: i64) i64;\n"
"fn print(s: str) i64 = { return rt_syscall(1, 1, s.ptr: i64, s.len: i64); };\n"