<shcv>
if all members of a union have a field, does the union also have that field?
<shcv>
I guess that wouldn't help in my case anyway, so nvm
<pixelherodev>
I mean, not really
<pixelherodev>
There's no way to access it without going through the direct parent
dimenus has joined #zig
alexnask has quit [Quit: Leaving]
stripedpajamas has quit [Quit: sleeping...]
aerona has joined #zig
dimenus has quit [Ping timeout: 240 seconds]
doublex has quit [Read error: Connection reset by peer]
doublex_ has joined #zig
doublex_ has quit [Read error: Connection reset by peer]
doublex has joined #zig
doublex has quit [Read error: Connection reset by peer]
doublex has joined #zig
doublex has quit [Read error: Connection reset by peer]
doublex has joined #zig
doublex has quit [Read error: Connection reset by peer]
doublex has joined #zig
dimenus has joined #zig
marijnfs has joined #zig
marijnfs_ has quit [Ping timeout: 246 seconds]
doublex_ has joined #zig
doublex_ has quit [Read error: Connection reset by peer]
doublex_ has joined #zig
doublex_ has quit [Read error: Connection reset by peer]
doublex_ has joined #zig
doublex has quit [Ping timeout: 264 seconds]
doublex_ has quit [Read error: Connection reset by peer]
dimenus has quit [Quit: WeeChat 2.8]
dimenus has joined #zig
procnto has quit [Ping timeout: 246 seconds]
procnto has joined #zig
guan has quit [Read error: Connection reset by peer]
betawaffle has quit [Ping timeout: 272 seconds]
wjlroe has quit [Ping timeout: 272 seconds]
guan has joined #zig
betawaffle has joined #zig
dimenus has quit [Ping timeout: 258 seconds]
wjlroe has joined #zig
<andrewrk>
hmm alright so I have allocated registers for operands of an add instruction, and a register for the result. now I have to do instruction selection. should be fun, I've never done this before
heitzmann has quit [Ping timeout: 260 seconds]
dddddd has quit [Ping timeout: 244 seconds]
heitzmann has joined #zig
<aerona>
items.len is the proper way to retrieve the length from an ArrayList right?
<aerona>
when i append to the array list the len gets incremented to 2 but later during a test it's only set to 1
<aerona>
funnily enough if i manually change the len to 2 in my test i can retrieve the other. though it's the same value as the first element
<andrewrk>
aerona, that's right
doublex__ is now known as doublex
<pixelherodev>
andrewrk: instruction selection?
<pixelherodev>
You mean determining which add variant to use?
<pixelherodev>
Oh, and what type of register allocator?
<pixelherodev>
Is the register allocator platform-specific?
<andrewrk>
so far the register allocator is architecture-agnostic, so it doesn't require reimplementing for new architectures
<andrewrk>
yeah determining the add variant. looks pretty similar to the problem you solved for setting registers
<pixelherodev>
hmm
<pixelherodev>
I think I have that for c3 already...
<pixelherodev>
That works, but is probably not 100% efficient
<andrewrk>
nice, thanks!
<andrewrk>
wow this looks nearly identical to what I'm about to do
<andrewrk>
One Way To Do Things, eh?
<pixelherodev>
:)
<pixelherodev>
Let me know if yours differs seriously
<pixelherodev>
I'll update mine ;)
<andrewrk>
the register allocator is going to differe seriously. I believe you have actually implemented a solution to the problem that is reasonably fast at runtime, whereas I came up with something that maximizes compilation performance and compromises runtime perf
<andrewrk>
I think it will do just fine though, it still takes instruction lifetimes into account
<pixelherodev>
Uh, no? My register allocator was chosen for the opposite of that
<pixelherodev>
My register allocator was explicitly chosen because it has nearly no compile time overhead
<pixelherodev>
Rather, it provides decent runtime performance at minimal comptime / translation-time cost
<andrewrk>
oh, interesting. I thought you were implementing an academic paper or something
<pixelherodev>
It's based on one, yes
<pixelherodev>
One which was explicitly designed to be low-cost :)
<andrewrk>
cool
<pixelherodev>
Mind pushing to a branch so I can take a peek? :)
<andrewrk>
sure. btw how did you get rid of the `try`s in your add.zig code?
<pixelherodev>
... uh
<andrewrk>
are you able to figure out how much of a memory buffer to allocate ahead of time?
<pixelherodev>
Ah right
<pixelherodev>
It requires the caller to preallocate the full buffer
<pixelherodev>
I have a builder, not just assembler
<andrewrk>
how does the caller know?
<pixelherodev>
It builds the full block before assembling
<pixelherodev>
It does instruction selection :P
<pixelherodev>
I need to rework that a bit
<pixelherodev>
The builder should store the form to use as well, which will make the assembler marginally faster
<pixelherodev>
or I should copy you, and break each form into its own enum tag :P
<andrewrk>
I would love to get rid of all the `try` in codegen, I think it would speed things up. but it's tricky to know an upper bound on how much machine code will be generated
<pixelherodev>
andrewrk: how do you feel about me working on a C backend over other, more... productive things?
<pixelherodev>
:P
<andrewrk>
no prob. might need a lot of coordinate at first, but once things are basically let up it should be smooth sailing
<pixelherodev>
andrewrk: we don't need to get rid of it *everywhere*
<pixelherodev>
We can do it for source with known sizings
<andrewrk>
yeah good point
<pixelherodev>
Hmm, what's more fun, C *backend*, or C *frontend*?
<pixelherodev>
C backend would be awesome because it'd mean potentially replacing stage1 with a one-time dump (as you've mentioned as, how did you put it, "just an idea, not an actual plan"?)
<pixelherodev>
C *frontend* would be awesome because it'd allow removing the Clang dependency entirely
<pixelherodev>
and it could potentially be used for stage1 too
<andrewrk>
C backend is a smaller scoped project
<pixelherodev>
The same way that e.g. translate-c is used in stage1
<pixelherodev>
I know
<pixelherodev>
But C frontend is more rewarding IMO
<andrewrk>
idk, replacing stage1 seems like a pretty big reward
<pixelherodev>
Reduce our dependencies with lighter, faster, simpler code which we control and which won't break on Clang 11 or something :P
<pixelherodev>
True, but it would still mean depending on Clang
<pixelherodev>
Simpler bootstraps versus replacing stage1 earlier...
<pixelherodev>
Hmm
<andrewrk>
simpler bootstraps is not a pressing issue
<pixelherodev>
I know
<andrewrk>
I'm just voting :)
<pixelherodev>
But I'm also thinking in terms of what bugs me the most about Zig right now
<pixelherodev>
Bootstrapping / LLVM / Clang bothers me more than the fact that stage2 isn't actually done yet
<pixelherodev>
Ooh, here's a thought
<pixelherodev>
... nah never mind
<leeward>
not me
<leeward>
I'm bothered more by missing features that depend on stage2.
<pixelherodev>
CBE should be simple too
<leeward>
If we're voting, I'd rather have a stable implementation than a fast/lightweight one.
<pixelherodev>
No reason I can't do both
<pixelherodev>
leeward: I don't consider stage1 stable
<pixelherodev>
precisely because it depends on clang + LLVM
<leeward>
Sure, but if it builds stage2 who cares?
<leeward>
I mean, obviously you do.
<pixelherodev>
Stage2 depends on stage1.
<pixelherodev>
Not at runtime of course
<pixelherodev>
But any code needed for stage1 is needed for stage2
<pixelherodev>
Which means any instability brought by LLVM / Clang affects stage2 too
<leeward>
So stage2 doesn't get to use all the bells and whistles, but it means my code, which is built by stage2, does.
<leeward>
And LLVM is a large, well-funded project. The fact that they have issues doesn't deter me from depending on them a bit longer.
<leeward>
Maybe (definitely) I don't understand all the issues, but that's my high level view.
<andrewrk>
to be clear I personally am working full steam ahead on stage2, regardless of what pixelherodev decides to do with his time
<leeward>
I gathered that.
<leeward>
but thanks for being explicit
<pixelherodev>
^ that's very true
<pixelherodev>
Personally, I'd rather do the frontend, but the backend is definitely more useful to the Zig project, so I'm doing that first
<andrewrk>
C frontend => C backend would be amusing
<pixelherodev>
Could be useful, actually
<pixelherodev>
If we did lazy evaluation and such ;)
<pixelherodev>
As a sort of sanity check; any input for which the output doesn't semantically match should be looked over
stripedpajamas has joined #zig
stripedpajamas has quit [Quit: sleeping...]
<pixelherodev>
andrewrk: you said you want to lock down ZIR as an implementation detail, right?
<pixelherodev>
Explicitly don't let people target it from other projects?
<andrewrk>
I'm fairly certain it's going to remain an implementation detail
<pixelherodev>
Good
<pixelherodev>
It causes some minor inconvenience to me right now, but I think it's worth it
<pixelherodev>
anywho
<pixelherodev>
CBE work coming soon TM
stripedpajamas has joined #zig
<pixelherodev>
:)
<aerona>
so i picked up zig-toml again and rewrote in a recursive style so it should be easier to add the rest of the toml spec
<aerona>
i also added support for array of tables
<pixelherodev>
andrewrk: did you push your changes to a branch?
<pixelherodev>
... hmm, CBE is going to take more work than I thought
<pixelherodev>
`arch` isn't defined
<pixelherodev>
Unless the CBE produces arch-specific C, which would make sense I suppose
<pixelherodev>
but that defeats the purpose
<andrewrk>
pixelherodev, oops. ok it's pushed to the register-allocation branch
<andrewrk>
yes it would produce arch-specific C
<andrewrk>
that's not even a question
<andrewrk>
no that doesn't defeat the purpose
<pixelherodev>
Wait, really?
<pixelherodev>
Why?
<pixelherodev>
That means we need to know all the details of every possible target
<pixelherodev>
With agnostic C, we can require stripped-down details (pointer size, for instance) and leave that to the C compiler (or, eventually, our C frontend :P)
penguinicus has quit [Ping timeout: 245 seconds]
<andrewrk>
zig's semantic analysis does know all the details of every possible target, that's the point
<pixelherodev>
let's say I'm targeting, for instance, $NEW_HIP_ISA
<pixelherodev>
There's a new microcontroller ISA, it's obscure, Zig has no details
<pixelherodev>
What I'm basically envisioning is you just give it the bare minimum, and let the C compiler handle the rest
<pixelherodev>
Or let's use SDCC as an example
Mulugruntz has joined #zig
<pixelherodev>
SDCC supports some esoteric targets, like Padauk
<pixelherodev>
Programming Zig to know every detail of every target means more work for every target
<pixelherodev>
Why should we need to care about the target if we're emitting C?
<andrewrk>
good question, let's examine how it would work if c replaced the architecture in the triple
waleee-cl has quit [Quit: Connection closed for inactivity]
<pixelherodev>
?
<andrewrk>
e.g. instead of riscv64-linux-gnu it would be c-linux-gnu
<pixelherodev>
Right
<pixelherodev>
Is that what I should use for the initial implementation?
<aerona>
also here's a mustache renderer if anyone has need for such a thing github.com/aeronavery/zig-mustache
<pixelherodev>
Actually, would the ABI matter?
<pixelherodev>
The C compiler should tackle that
<pixelherodev>
It would be c-$OS I think
<pixelherodev>
Or c-$OS-none
<andrewrk>
one problem would be how many bits to make the pointer size
<pixelherodev>
Not necessarily
<pixelherodev>
There's a definition for pointer-sized-ints, no?
<pixelherodev>
uintptr ?
<andrewrk>
zig code: if (@sizeOf(usize) == 8) foo() else bar(); // zig cannot compile this code without knowing at compile time what the pointer size is
<pixelherodev>
ahh, right
<pixelherodev>
Gotcha
<pixelherodev>
c-$os-ptrsize?
<pixelherodev>
Have ptrsize replace the ABI?
<andrewrk>
ok so I gave you only 1 example
<pixelherodev>
True
<andrewrk>
however this problem is basically present with every single thing that is specific to an architecture
<pixelherodev>
Could have those specified elsewhere?
<pixelherodev>
Rather
<andrewrk>
so.... there's a really convenient way to specify these things
<pixelherodev>
--target c-$os-platformfile
<pixelherodev>
Have a file passed as part of the triple which specifies all of it
<andrewrk>
in fact it involves doing nothing new! just pass an actual architecture
<pixelherodev>
What's wrong with doing it this way though?
<andrewrk>
"platformfile" would have exactly all the details that are encoded by the architecture part of the triple
<andrewrk>
we already have this problem solved
<pixelherodev>
Honestly, I don't think i can think of anything other than pointer size that needs to be specified
<pixelherodev>
Hmm, vectors and SIMD, so some CPU features possibly
<pixelherodev>
for intrinsics
<pixelherodev>
I'm probably missing other things too
<pixelherodev>
Okay, so `arch-os-c`?
<andrewrk>
making it one of the C ABI enums could be an interesting idea. I'm not against it
<pixelherodev>
alternately, we can decouple it from the triple
<pixelherodev>
detriple it?
<pixelherodev>
--target blah --c
<pixelherodev>
Are comments included in the AST parser?
<pixelherodev>
Thinking ahead a bit :P
<pixelherodev>
yeah, they've got to be; that's how docgen and zig fmt work
<aerona>
one last thing before i go to bed, an orm i've been working on in my free time github.com/aeronavery/zig-orm
aerona has quit [Quit: Leaving]
penguinicus has joined #zig
opDispatch has quit [Quit: Konversation terminated!]
gazler__ has quit [Read error: Connection reset by peer]
gazler__ has joined #zig
<andrewrk>
pixelherodev, why is it u7 instead of u8? if ((try std.math.absInt(IMM)) < std.math.maxInt(u7))
<pixelherodev>
Sign
<pixelherodev>
We don't care about the sign
<pixelherodev>
It's a signed 8-bit value stored as u8
<pixelherodev>
... Rather
<pixelherodev>
Sorry, that was completely wrong
<pixelherodev>
Because it *isn't* signed, but it *will* be
<pixelherodev>
Notice the absInt
<pixelherodev>
We're going from a signed number to unsigned
<pixelherodev>
But the final encoding is effectively i8
<pixelherodev>
That should probably be <= though
<pixelherodev>
andrewrk: was the remotely clear? :P
<pixelherodev>
Let's say we have, -100, and 244
<pixelherodev>
absInt(-100) => 100, which is less than maxInt(u7), and thus okay, and encodable
<andrewrk>
so the cpu sign extends the immediate
<pixelherodev>
absInt(244) => 244 - it can be encoded as u8, but - exactly
<pixelherodev>
That should probably be in the comments, yes
stripedpajamas has quit [Quit: sleeping...]
dermetfan has joined #zig
lemmi has joined #zig
_Vi has joined #zig
fengb has quit [Quit: killed]
return0e[m] has quit [Quit: killed]
alva has quit [Quit: killed]
ifreund[m] has quit [Quit: killed]
pmwhite has quit [Quit: killed]
Snektron has quit [Quit: killed]
hamoko[m] has quit [Quit: killed]
BaroqueLarouche has quit [Quit: killed]
penguinicus has quit [Remote host closed the connection]
Mulugruntz has quit [Ping timeout: 264 seconds]
Mulugruntz has joined #zig
pmwhite has joined #zig
hamoko[m] has joined #zig
alva has joined #zig
return0e[m] has joined #zig
ifreund[m] has joined #zig
Snektron has joined #zig
fengb has joined #zig
BaroqueLarouche has joined #zig
ur5us has quit [Ping timeout: 244 seconds]
knebulae has joined #zig
<pixelherodev>
andrewrk: so what's the conclusion?
alexnask has joined #zig
gpanders has quit [Ping timeout: 246 seconds]
gpanders has joined #zig
ofelas has quit [Ping timeout: 240 seconds]
cren has joined #zig
<pixelherodev>
I want to get to work on CBE *today*, but I want to make sure that I'm doing it in a way that benefits the Zig community, which means that I need to know the desired behavior before I get to work :)
ofelas has joined #zig
cren has quit [Ping timeout: 245 seconds]
nikita` has joined #zig
r4pr0n has joined #zig
dongcarl has quit [Quit: Ping timeout (120 seconds)]
dongcarl has joined #zig
waleee-cl has joined #zig
cren has joined #zig
cren has quit [Remote host closed the connection]
penguinicus has joined #zig
cren has joined #zig
gpanders has quit [Ping timeout: 265 seconds]
gpanders has joined #zig
<scientes>
pixelherodev, what is CBE?
<alexnask>
C backend
<alexnask>
(I think)
<scientes>
pixelherodev, you can't just cut off the signed bit
<scientes>
pixelherodev, because of that sneaky value of MIN_INT
<pixelherodev>
C backend, yeah
<pixelherodev>
scientes: doesn't matter.
<scientes>
it always becomes an unsiged number of the same number of bits that went in
<pixelherodev>
Why would that change anything?
<scientes>
try MIN_INT * -1
<pixelherodev>
... again, so?
<scientes>
and experience a fun SIGFPE
<mq32>
scientes: this should not throw a SIGFPE :D
<mq32>
it's integers
<pixelherodev>
^
<scientes>
mq32, try it
<scientes>
the really strange thing is that % -1 can also throw SIGFPE
<scientes>
but only on older hardware
<pixelherodev>
Plus, That's with / , not * I thought
<scientes>
because it uses division in the back-end
<scientes>
ahh yes, the multiplication just winds-around
<pixelherodev>
`If integer math results in a signal being delivered, POSIX requires it to be SIGFPE`
<scientes>
and you get MIN_INT as the output
<scientes>
which is pretty strange
<scientes>
MIN_INT * -1 == MIN_INT
<mq32>
scientes: yields a warning, runs fine
<pixelherodev>
Again, why is that an issue?
<pixelherodev>
Let's say the value is 10000000
<scientes>
pixelherodev, because you can't cut off the signed bit in abs()
<pixelherodev>
Wait, wrong value
<pixelherodev>
scientes: ... again, why not?
<scientes>
or else that edge-case does not work
<mq32>
division works as well
<pixelherodev>
Talk to me like I'm a child :P
<scientes>
abs(MIN_INT)==INT_MAX+1
<pixelherodev>
Why is there an issue here
<scientes>
^^^
<pixelherodev>
and?
<mq32>
scientes: where's the problem?
<scientes>
so if you cut off the bit you can't fit that value
<mq32>
it's not possible to abs() MIN_INT
<mq32>
because the value is not representable in int
<scientes>
MIN_INT8== -128
<pixelherodev>
Yes
<mq32>
which isn't representable in a INT8
<scientes>
so if you cut it from a i8 to a u7, then you can only it 127
<scientes>
*fit
<pixelherodev>
And that's supposed to be... wait hmm
<pixelherodev>
I think I see your point.
<pixelherodev>
Yeah, I realized that with 10000000
<pixelherodev>
That's -128, not "-0"
<scientes>
exactly
<pixelherodev>
Wait
<pixelherodev>
is it?
<pixelherodev>
... yes
<scientes>
it is
<pixelherodev>
I'm just tired
<scientes>
11111111 is -1
<scientes>
and 10000000 is -128
<pixelherodev>
Right I got that
<pixelherodev>
(I know how two's complement works, but I should be asleep rn :P)
<scientes>
my point is you cant cut off the signed bit because of that corner-case
<pixelherodev>
No I got that
<pixelherodev>
I mean
<pixelherodev>
`or == -128`
<pixelherodev>
:P
<pixelherodev>
That's probably the most efficient way to do the check
<scientes>
pixelherodev, you just multiply by -1 if < 0
<pixelherodev>
Hmm, what's the best Ziggy way to say "if this fits in a signed int"?
<pixelherodev>
That's not any better though, is it?
<pixelherodev>
That's still just 128
<scientes>
pixelherodev, that's fine
<pixelherodev>
"if this fits in signed int of type blah"
<scientes>
abs() should CHANGE the type
<pixelherodev>
`if (val_as_i32 fits in i8)
<scientes>
but keep the bit width
<pixelherodev>
That's the problem though
<pixelherodev>
abs(i7) cannot always fit in u8
<pixelherodev>
-128 is valid i7 but 128 isn't valid u7
<scientes>
abs(i7) can always fit in u7
<scientes>
i7 is -64 to 63
<pixelherodev>
Ah right
<pixelherodev>
abs(i8) rather
<scientes>
can always fit in u8
<scientes>
but NOT u7
<pixelherodev>
ahhhh, gotcha
<scientes>
because of the minint case
<pixelherodev>
Wait
<pixelherodev>
I'm not cutting the sign bit though
<pixelherodev>
I mean, it's using an inefficient form sure
<pixelherodev>
(for that edge case)
<scientes>
its a little tricky to do this conversion in place
<scientes>
when you are changing the type
<pixelherodev>
time for std.math.fitsIn ? :P
<scientes>
no
<pixelherodev>
if (i32 fits in i8)
<scientes>
you should just do it without any standard lib at all
<scientes>
its simple enough
<pixelherodev>
what's the best way to do that
<pixelherodev>
arguably you should do that for e.g. max too
<scientes>
i actually like the absInt cause it explains what you are doing
<pixelherodev>
scientes: that's ambiguous.
<scientes>
try std.math.absInt(IMM)) < 0b1000000)
<scientes>
and why does absInt throw a friggen error?
<scientes>
that makes no sense
<pixelherodev>
That'd be u7 < comptime_int
<pixelherodev>
I didn't mean "the compiler complained, I tried"
<pixelherodev>
I mean that's not readable.
<pixelherodev>
It's not obvious that that's going to do
<pixelherodev>
scientes: overflow
<pixelherodev>
if input to absInt == minInt(@TypeOf(x)) it overflows
<scientes>
pixelherodev, that is why I avoid stdlib when I can
<scientes>
that is idiocy
<pixelherodev>
send a patch.
<scientes>
I will, but I generally avoid it because I get too much bike shedding
<pixelherodev>
To paraphrase: "if you don't vote [by contributing], I don't care about your complaints about the current system"
<scientes>
that is a good attitude
<pixelherodev>
scientes: you actually planning on patching that?
<pixelherodev>
I'll do it if you don't want to
<pixelherodev>
huh
<pixelherodev>
mq32: 'The Single Unix Specification defines SIGFPE as "Erroneous arithmetic operation". It's confusingly named after floating point, but in a normal system with the FPU in its default state, only integer math will raise it'
<mq32>
lol
<mq32>
didn't happen in my case though
<scientes>
yeah you have to use divide
<scientes>
64/32 will also trigger it, but you can't call that from C even though the hardware can do it better
<pixelherodev>
And be on x86
<pixelherodev>
and POSIX
<pixelherodev>
and other platform details
<scientes>
i think arm will throw it too
<pixelherodev>
Nope
<scientes>
then what does it return?
<mq32>
funky
<mq32>
you __have__ to use explicit runtime variables
<mq32>
otherwise gcc will just remove i /= -1;
<pixelherodev>
Also depends on optimizations
<mq32>
pixelherodev: on arm qemu: uncaught target signal 4 (Illegal instruction) - core dumped
* pixelherodev
shrugs
<pixelherodev>
never mind then
<scientes>
arm does normalize NaN which is nice
<scientes>
makes NaN packing much easier
<scientes>
yeah I don't like patching stdlib either because the way it is put together everything depends on everything else
<mq32>
scientes: that's the nature of a "stdlib"
<scientes>
not really
<scientes>
its egregious
<scientes>
like you can just do @import("std")
<scientes>
but no, everything does @import("../../std.zig")
* mq32
googles egregious
<mq32>
scientes: you know the image of a snake biting it's own tail?
<mq32>
you cannot do @import("mypackage") in package "mypackage"
<scientes>
you can in std
<scientes>
it works fine
<mq32>
huh?
<scientes>
std actually makes sure that it works and will throw an error if you don't do it