w6c+selfhost: cgen N_DOT slice-field through *T root in call args (closes #29)
This commit is contained in:
@@ -4487,6 +4487,28 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
areg(D_BX));
|
||||
goto dot_done;
|
||||
}
|
||||
if (fu && fu->kind == TY_SLICE) {
|
||||
/* Slice leaf: load all three header
|
||||
* words into (AX=ptr, BX=len, CX=cap)
|
||||
* so the value follows the canonical
|
||||
* slice-rhs convention. base_reg may
|
||||
* be CX (global / `*T` root); load
|
||||
* .cap LAST so the base survives the
|
||||
* earlier reads. */
|
||||
ins2(c, A_MOVQ,
|
||||
amem(base_reg,
|
||||
base_disp + total_off + 0),
|
||||
areg(D_AX));
|
||||
ins2(c, A_MOVQ,
|
||||
amem(base_reg,
|
||||
base_disp + total_off + 8),
|
||||
areg(D_BX));
|
||||
ins2(c, A_MOVQ,
|
||||
amem(base_reg,
|
||||
base_disp + total_off + 16),
|
||||
areg(D_CX));
|
||||
goto dot_done;
|
||||
}
|
||||
int g_isf32 = 0;
|
||||
if (fld_isfloat(leaf_type, &g_isf32)) {
|
||||
int mov = g_isf32 ? A_MOVSS : A_MOVSD;
|
||||
@@ -4658,6 +4680,22 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
areg(D_BX));
|
||||
break;
|
||||
}
|
||||
/* slice field: load (ptr, len, cap) into (AX, BX, CX)
|
||||
* so the value flows through the slice-rhs convention.
|
||||
* base_reg may be CX for globals; load .cap LAST so
|
||||
* the base survives the earlier reads. */
|
||||
if (str_fu && str_fu->kind == TY_SLICE) {
|
||||
ins2(c, A_MOVQ,
|
||||
amem(base_reg, base_disp + (int)f->offset + 0),
|
||||
areg(D_AX));
|
||||
ins2(c, A_MOVQ,
|
||||
amem(base_reg, base_disp + (int)f->offset + 8),
|
||||
areg(D_BX));
|
||||
ins2(c, A_MOVQ,
|
||||
amem(base_reg, base_disp + (int)f->offset + 16),
|
||||
areg(D_CX));
|
||||
break;
|
||||
}
|
||||
/* f64/f32 field: route through X0 (MOVSD/MOVSS).
|
||||
* Loading via MOVQ AX would put the bits in the
|
||||
* integer reg, and any downstream consumer that
|
||||
@@ -4722,6 +4760,22 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
ins2(c, A_MOVQ, areg(D_CX), areg(D_BX));
|
||||
break;
|
||||
}
|
||||
/* slice field through *struct: load (ptr, len,
|
||||
* cap) into (AX, BX, CX). BX holds the *struct
|
||||
* pointer, so load .len LAST — the earlier loads
|
||||
* still index off the original base. */
|
||||
if (str_fu && str_fu->kind == TY_SLICE) {
|
||||
ins2(c, A_MOVQ,
|
||||
amem(D_BX, (int)f->offset + 0),
|
||||
areg(D_AX));
|
||||
ins2(c, A_MOVQ,
|
||||
amem(D_BX, (int)f->offset + 16),
|
||||
areg(D_CX));
|
||||
ins2(c, A_MOVQ,
|
||||
amem(D_BX, (int)f->offset + 8),
|
||||
areg(D_BX));
|
||||
break;
|
||||
}
|
||||
/* f64/f32 field via *struct: load into X0.
|
||||
* BX already holds the struct pointer from
|
||||
* the MOVQ amem(D_BP,off) above. */
|
||||
@@ -4772,6 +4826,21 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
areg(D_AX));
|
||||
goto dot_done;
|
||||
}
|
||||
/* slice field: load (ptr, len, cap) into
|
||||
* (AX, BX, CX). AX is the *struct base, so
|
||||
* load .ptr (which targets AX) LAST. */
|
||||
if (fu && fu->kind == TY_SLICE) {
|
||||
ins2(c, A_MOVQ,
|
||||
amem(D_AX, (int)f->offset + 8),
|
||||
areg(D_BX));
|
||||
ins2(c, A_MOVQ,
|
||||
amem(D_AX, (int)f->offset + 16),
|
||||
areg(D_CX));
|
||||
ins2(c, A_MOVQ,
|
||||
amem(D_AX, (int)f->offset + 0),
|
||||
areg(D_AX));
|
||||
goto dot_done;
|
||||
}
|
||||
/* f64/f32 chained field: read into X0. */
|
||||
int g_isf32 = 0;
|
||||
if (fld_isfloat(ft, &g_isf32)) {
|
||||
|
||||
Reference in New Issue
Block a user