Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nifc: add alignof & offsetof, make sizeof only take type #120

Merged
merged 3 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion doc/nifc-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ Expr ::= Number | CharLiteral | StringLiteral |
(or Expr Expr) | # "||"
(not Expr) | # "!"
(neg Type Expr) |
(sizeof Expr) |
(sizeof Type) |
(alignof Type) |
(offsetof Type SYMBOL) |
(oconstr Type (kv Symbol Expr)*) | # (object constructor){...}
(aconstr Type Expr*) | # array constructor
(add Type Expr Expr) |
Expand Down
15 changes: 14 additions & 1 deletion src/nifc/amd64/genasm_e.nim
Original file line number Diff line number Diff line change
Expand Up @@ -785,10 +785,23 @@ proc genx(c: var GeneratedCode; t: Tree; n: NodePos; dest: var Location) =
genAddr c, t, n.firstSon, dest
of SizeofC:
# we evaluate it at compile-time:
let a = getAsmSlot(c, n.firstSon)
let a = typeToSlot(c, n.firstSon)
let typ = AsmSlot(kind: AUInt, size: WordSize, align: WordSize)
let d = immediateLoc(uint(a.size), typ)
into c, dest, d
of AlignofC:
# we evaluate it at compile-time:
let a = typeToSlot(c, n.firstSon)
let typ = AsmSlot(kind: AUInt, size: WordSize, align: WordSize)
let d = immediateLoc(uint(a.align), typ)
into c, dest, d
of OffsetofC:
let (obj, fld) = sons2(t, n)
let field = t[fld].litId
let ftyp = c.fields[field]
let typ = AsmSlot(kind: AUInt, size: WordSize, align: WordSize)
let d = immediateLoc(uint(ftyp.offset), typ)
into c, dest, d
of CallC: genCall c, t, n, dest
of AddC: typedBinOp AddT
of SubC: typedBinOp SubT
Expand Down
10 changes: 9 additions & 1 deletion src/nifc/amd64/genasm_s.nim
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,16 @@ proc genConstData(c: var GeneratedCode; t: Tree; n: NodePos) =
let arg = n.firstSon
genConstData c, t, arg
of SizeofC:
let a = getAsmSlot(c, n.firstSon)
let a = typeToSlot(c, n.firstSon)
c.genIntLit a.size, info
of AlignofC:
let a = typeToSlot(c, n.firstSon)
c.genIntLit a.align, info
of OffsetofC:
let (obj, fld) = sons2(t, n)
let field = t[fld].litId
let ftyp = c.fields[field]
c.genIntLit ftyp.offset, info
else:
error c.m, "unsupported expression for const: ", t, n

Expand Down
2 changes: 1 addition & 1 deletion src/nifc/amd64/register_allocator.nim
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ proc allocRegsForProc(c: var GeneratedCode; t: Tree; n: NodePos; weights: Table[
let k = t[n].kind
case k
of Empty, Ident, SymDef, Sym, IntLit, UIntLit, FloatLit, CharLit, StrLit, Err,
NilC, FalseC, TrueC, SizeofC, InfC, NegInfC, NanC:
NilC, FalseC, TrueC, SizeofC, AlignofC, OffsetofC, InfC, NegInfC, NanC:
discard
of StmtsC, ScopeC:
c.openScope()
Expand Down
10 changes: 10 additions & 0 deletions src/nifc/cprelude.nim
Original file line number Diff line number Diff line change
Expand Up @@ -260,5 +260,15 @@ typedef NU8 NU;

#define N_NOINLINE_PTR(rettype, name) rettype (*name)

#if defined(_MSC_VER)
# define NIM_ALIGN(x) __declspec(align(x))
# define NIM_ALIGNOF(x) __alignof(x)
#else
# define NIM_ALIGN(x) __attribute__((aligned(x)))
# define NIM_ALIGNOF(x) __alignof__(x)
#endif

#include <stddef.h>

"""

18 changes: 17 additions & 1 deletion src/nifc/genexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,23 @@ proc genx(c: var GeneratedCode; t: Tree; n: NodePos) =
let arg = n.firstSon
c.add "sizeof"
c.add ParLe
genx c, t, arg
genType c, t, arg
c.add ParRi
of AlignofC:
let arg = n.firstSon
c.add "NIM_ALIGNOF"
c.add ParLe
genType c, t, arg
c.add ParRi
of OffsetofC:
let (typ, mem) = sons2(t, n)
c.add "offsetof"
c.add ParLe
genType c, t, typ
c.add Comma
let lit = t[mem].litId
let name = mangle(c.m.lits.strings[lit])
c.add name
c.add ParRi
of CallC: genCall c, t, n
of AddC: typedBinOp " + "
Expand Down
2 changes: 1 addition & 1 deletion src/nifc/native/analyser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ proc analyseVarUsages(c: var Context; t: Tree; n: NodePos) =
let k = t[n].kind
case k
of Empty, Ident, SymDef, IntLit, UIntLit, FloatLit, CharLit, StrLit, Err,
NilC, FalseC, TrueC, SizeofC, InfC, NegInfC, NanC:
NilC, FalseC, TrueC, SizeofC, AlignofC, OffsetofC, InfC, NegInfC, NanC:
discard
of StmtsC, ScopeC:
c.openScope()
Expand Down
4 changes: 3 additions & 1 deletion src/nifc/nifc_grammar.nif
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
(or Expr Expr)
(not Expr)
(neg Type Expr)
(sizeof Expr)
(sizeof Type)
(alignof Type)
(offsetof Type SYMBOL)
(oconstr Type (ZERO_OR_MANY (kv SYMBOL Expr)))
(aconstr Type (ZERO_OR_MANY Expr))
(add Type Expr Expr)
Expand Down
2 changes: 2 additions & 0 deletions src/nifc/nifc_model.nim
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type
NotC = "not"
NegC = "neg"
SizeofC = "sizeof"
AlignofC = "alignof"
OffsetofC = "offsetof"
OconstrC = "oconstr"
AconstrC = "aconstr"
KvC = "kv"
Expand Down
11 changes: 10 additions & 1 deletion src/nifc/preasm/genpreasm_e.nim
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,17 @@ proc genx(c: var GeneratedCode; t: Tree; n: NodePos; mode: XMode) =
genx c, t, n.firstSon, WantAddr
of SizeofC:
# we evaluate it at compile-time:
let a = getAsmSlot(c, n.firstSon)
let a = typeToSlot(c, n.firstSon)
genIntLit c, a.size, info
of AlignofC:
# we evaluate it at compile-time:
let a = typeToSlot(c, n.firstSon)
genIntLit c, a.align, info
of OffsetofC:
let (obj, fld) = sons2(t, n)
let field = t[fld].litId
let ftyp = c.fields[field]
genIntLit c, ftyp.offset, info
of CallC: genCall c, t, n
of AddC: typedBinOp AddT
of SubC: typedBinOp SubT
Expand Down
2 changes: 1 addition & 1 deletion src/nifc/typenav.nim
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ proc getType*(m: var Module; t: Tree; n: NodePos): TypeDesc =
of FldC:
let v = asFieldDecl(t, n)
result = TypeDesc(p: v.typ)
of IntLit, SizeofC: result = createIntegralType(m.lits, IntC, "-1")
of IntLit, SizeofC, AlignofC, OffsetofC: result = createIntegralType(m.lits, IntC, "-1")
of UIntLit: result = createIntegralType(m.lits, UIntC, "-1")
of FloatLit, InfC, NegInfC, NanC: result = createIntegralType(m.lits, FloatC, "64")
of CharLit: result = createIntegralType(m.lits, CharC, "8")
Expand Down
Loading
Loading