summary refs log tree commit diff
AgeCommit message (Collapse)Author
2022-03-14arm64/abi: fix big aggregates passed on the stackQuentin Carbonneaux
The riscv test abi8.ssa caught a bug in the arm backend. It turns out we were using the wrong class when loading pointers to aggregates from the stack. The fix is simple and mirrors what is done in the riscv abi.
2022-03-11dust off antique .tagQuentin Carbonneaux
2022-03-10rv64: plug holes in the abiQuentin Carbonneaux
Many things got fixed, but the most notable change is the proper support of floating point types in aggregates. Minor fixes: - selpar() did not deal correctly with Cfpint - typclass() was reading out of bounds in the gp/fp arrays - support for env calls
2022-03-10two new tests in abi5.ssaQuentin Carbonneaux
They are meant to exercise the hardware floating-point calling convention of the risc-v target.
2022-03-10new abi stress testQuentin Carbonneaux
2022-03-08flag types defined as unionsQuentin Carbonneaux
The risc-v abi needs to know if a type is defined as a union or not. We cannot use nunion to obtain this information because the risc-v abi made the unfortunate decision of treating union { int i; } differently from int i; So, instead, I introduce a single bit flag 'isunion'.
2022-03-08cosmeticsQuentin Carbonneaux
2022-03-07doc: export function main in hello world examplelincoln auster [they/them]
This enables the example to be compiled and run as-is, without any additional modification.
2022-02-27rv64: formatting and bug fix in epilogueQuentin Carbonneaux
2022-02-27doc: Add missing neg entry to indexScott Graham
2022-02-27rv64: cosmetics in iselQuentin Carbonneaux
2022-02-25disable pie for rv64 testsQuentin Carbonneaux
2022-02-25improve consistency in arm64 and rv64 abisQuentin Carbonneaux
2022-02-24parse: allow string after first data itemPaul Ouellette
2022-02-24doc: minor fixesPaul Ouellette
2022-02-24fix folding of shifts of word operand by >32Paul Ouellette
2022-02-17add rv64 backendMichael Forney
It is mostly complete, but still has a few ABI bugs when passing floats in structs, or when structs are passed partly in register, and partly on stack.
2022-02-17test: add c[u]od checks to isel2 and add new integer compare test isel3Michael Forney
2022-02-17cfg: remove unnecessary check for jump typeMichael Forney
This condition should match any jump with two successors. This is needed on riscv64, where there is no flags register, so Jjnz is used all the way to emit().
2022-02-17Revert "skip jump arguments in rega"Michael Forney
This reverts commit 028534d9897079bf64559dca0402bc59a956ce46. riscv64 will have jump arguments with type RTmp.
2022-02-17spill: consider jump argument as use of registerMichael Forney
2022-02-11document the automatic use of bssQuentin Carbonneaux
2022-02-11gas: put zero data into .bss by defaultMichael Forney
This allows frontends to use BSS generically, without knowledge of platform-dependent details.
2022-02-11doc: fix name of export linkage flagPaul Ouellette
2022-02-02shared linkage logic for func/dataQuentin Carbonneaux
2022-01-31arm64: handle large slots in OcopyQuentin Carbonneaux
2022-01-31Do not use the asm keyword as a local variableDetlef Riekenberg
Signed-off-by: Detlef Riekenberg <wine.dev@web.de>
2022-01-28amd64/isel: nitsQuentin Carbonneaux
2022-01-28fix test/fpcnv (wrong spacing)Quentin Carbonneaux
2022-01-28update token hash paramsQuentin Carbonneaux
2022-01-28implement float -> unsigned castsBor Grošelj Simić
amd64 lacks instruction for this so it has to be implemented with float -> signed casts. The approach is borrowed from llvm.
2022-01-28implement unsigned -> float castsBor Grošelj Simić
amd64 lacks an instruction for this so it has to be implemented with signed -> float casts: - Word casting is done by zero-extending the word to a long and then doing a regular signed cast. - Long casting is done by dividing by two with correct rounding if the highest bit is set and casting that to float, then adding 1 to mantissa with integer addition
2022-01-23increase token limit to 255Bor Grošelj Simić
2022-01-23bump copyright yearQuentin Carbonneaux
2022-01-23check for fopen() errors for output fileBor Grošelj Simić
2022-01-23Add a negation instructionEyal Sawady
Necessary for floating-point negation, because `%result = sub 0, %operand` doesn't give the correct sign for 0/-0.
2021-12-05arm64: fix slots with offset >32kQuentin Carbonneaux
When slots are used with a large offset, the emitter generates invalid assembly code. That is caught later on by the assembler, but it prevents compilation of programs with large stack frames. When a slot offset is too large to be expressed as a constant offset to x29 (the frame pointer), emitins() inserts a late Oaddr instruction to x16 and replaces the large slot reference with x16. This change also gave me the opportunity to refactor the save/restore logic for callee-save registers. This fixes the following Hare issue: https://todo.sr.ht/~sircmpwn/hare/387
2021-11-22reuse previous address constants in fold()Michael Forney
parseref() has code to reuse address constants, but this is not done in other passes such as fold or isel. Introduce a new function newcon() which takes a Con and returns a Ref for that constant, and use this whenever creating address constants. This is necessary to fix folding of address constants when one operand is already folded. For example, in %a =l add $x, 1 %b =l add %a, 2 %c =w loadw %b %a and %b were folded to $x+1 and $x+3 respectively, but then the second add is visited again since it uses %a. This gets folded to $x+3 as well, but as a new distinct constant. This results in %b getting labeled as bottom instead of either constant, disabling the replacement of %b by a constant in subsequent instructions (such as the loadw).
2021-11-10fold: Prevent error when address is used as operandMichael Forney
2021-11-10bump NStringQuentin Carbonneaux
2021-11-10fold: Don't fold invalid addition/subtraction rather than failingMichael Forney
This may happen in a branch QBE doesn't realize is unreachable, for example (simplified from real code found in ncurses) data $str = { b "abcdef", b 0 } function l $f(w %x) { @start %.1 =w ceqw %x, 0 jnz %.1, @logic_join, @logic_right @logic_right %p =l call $strchr(l $str, w %x) %.2 =w ceql %p, 0 @logic_join %.3 =w phi @start %.1, @logic_right %.2 jnz %.3, @fail, @return @fail ret 0 @return %.4 =l sub %p, $str ret %.4 }
2021-11-08amd64: avoid reading past end of passed structMichael Forney
If the size of the struct is not a multiple of 8, the actual struct size may be different from the size reserved on the stack. This fixes the case where the struct is passed in memory, but we still may over-read a struct passed in registers. A TODO is added for now.
2021-11-08fix for sloppy reg->mem in arm64 abiQuentin Carbonneaux
Michael found a bug where some copies from registers to memory in the arm64 abi clobber the stack. The test case is: type :T = { w } function w $f() { @start %p =:T call $g() %x =w loadw %p ret %x } qbe will write 4 bytes out of bounds when pulling the result struct from its register. The same bug can be observed if :T's definition is {w 3}; in this case qbe writes 16 bytes in a slot of 12 bytes. This patch changes stkblob() to use the rounded argument size if it is going to be restored from registers. Relatedly, mem->reg loads for structs with size < 16 and != 8, are treated a bit sloppily both in the arm64 and in the sysv abis. That is much less harmful than the present bug.
2021-10-28new chacha20 testQuentin Carbonneaux
2021-10-26use unified diff format for test outputMichael Forney
This make it easier to understand the differences.
2021-10-26remove trailing whitespace from test/abi7.ssaMichael Forney
2021-10-26spill: fix regs assertionsQuentin Carbonneaux
Some arm64 abi tests have been failing for some time now. This fixes them by being a bit more careful with liveset management in spill.c. A late bsclr() call in spill.c may drop legitimately live registers in e.g., R12 =w add R12, 1 While it hurts for regs, it does not matter for ssa temps because those cannot be both in the arguments & return (by the ssa invariant). I added a check before bsclr() to make sure we are clearing only ssa temps. One might be surprised that any ssa temp may be live at this point. The reason why this is the case is the special handling of dead return values earlier in spill(). I think that it is the only case where the return value can be (awkwardly) live at the same time as the arguments, and I think this never happens with registers (i.e., we never have dead register- assigning instructions). I added an assert to check the latter invariant. Finally, there was a simple bug in the arm64 abi which I fixed: In case the return happens via a pointer, x8 needs to be marked live at the beginning of the function. This was caught by test/abi4.ssa.
2021-10-26arm64: Add LR to list of registers to saveMichael Forney
Tested-by: Thomas Bracht Laumann Jespersen <t@laumann.xyz> Fixes: https://todo.sr.ht/~sircmpwn/hare/312
2021-10-25arm64/emit.c: fix move instructions with big immediate valuesSudipto Mallick
Fixes #467. It assumes that the stack won't need to grow beyond 2^32 bytes. If that were to happen, we'd need another or at most two more `movk` instructions. Signed-off-by: Sudipto Mallick <smlckz@disroot.org>
2021-10-25arm64: handle copy of constant to slotMichael Forney
If registers spill onto the stack, we may end up with SSA like S320 =l copy 0 after rega(). Handle this case in arm64 emit().