cranelift: add arm32 backend#13854
Open
obeis wants to merge 18 commits into
Open
Conversation
First step towards a 32-bit ARM backend. This wires arm32 into the meta build, the isa::lookup path, and the codegen crate, and adds just enough of the MachInst/ABIMachineSpec plumbing to compile and emit a trivial function. An iconst.i32 followed by a return now lowers to real A32 (movw + bx lr) and is covered by filetests/isa/arm32/iconst.clif. Everything off that path is still a stub. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
Enough of the common instructions to lower straight-line integer code: mov/movw/movt/mvn, ldr/str and the sub-word and push/pop forms, add/sub/rsb in register and rotated-immediate forms, cmp/cmn, and the branch family (b, bl, bx, and conditional b<cond>). Each comes with its A32 encoding, operand handling, and pretty-printing. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
Rounds out the data-processing group: the logical ops (and/orr/eor/bic and register mvn), the shifts and rotates in both immediate and register forms, mul/mla/umull/smull, the flag-setting arithmetic (adds/subs/adcs/ sbcs, plus the adc/sbc opcodes), and the tst/teq tests. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
The remaining core integer operations: clz; sdiv/udiv behind a new has_idiv ISA setting; the sxtb/sxth/uxtb/uxth extends; rev/rev16/rbit; the mls/smlal/umlal fused multiplies; and a conditional-select pseudo built from a mov plus a mov<cond>. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
Adds encoders, operand handling, printing, and unit tests for the scalar-integer instructions the backend was still missing: the bitfield ops (bfc/bfi/sbfx/ubfx), the saturating arithmetic, sel/pkh/revsh/rrx/ udf, the full parallel add/sub family, the 16-bit and accumulating extends, the DSP multiplies, ldm/stm, the exclusive and acquire/release memory accesses, and the barriers. Most of these have no CLIF opcode that maps to them yet; they are here so the encoder is complete and the tests pin the bit patterns down. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
A direct call to a near/colocated callee becomes a bl with an Arm32Call relocation; call_indirect becomes a blx through a register. The call and indirect-call instructions record the safepoint and stack map, pop the callee's stack arguments, and load any stack-returned values. Both forms are treated as calls by call_type/is_safepoint so the frame is set up and lr is preserved around them -- getting that wrong for the indirect case corrupts the return address. Far calls, return_call, and try_call are left for later. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
An i64 lives in a (lo, hi) pair of 32-bit registers. rc_for_type returns two Int registers for I64, and the ABI passes 64-bit arguments in even-aligned pairs (r0:r1 / r2:r3) per AAPCS, spilling to the 8-aligned stack when they run out. Lowers iconst, add/sub via the adds/adc and subs/sbc carry chains, the bitwise ops per half, iconcat/isplit, the extends and reduce between i32 and i64, and 64-bit load/store as two word accesses. The i64 rules take an explicit priority so ISLE doesn't have to prove them disjoint from the fits_in_32 rules. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
imul.i64 expands to umull plus two mla for the low 64 bits of the product. Constant-amount ishl/ushr/sshr use a funnel sequence: for shifts below 32 an orr of two 32-bit shifts, and for shifts of 32 or more a single shift with a zero or sign fill. Variable-amount i64 shifts are still unimplemented. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
icmp on i64 operands, both as a value and fused into brif. eq/ne reduce the halves with eor/eor/orrs; the ordering comparisons subtract the pair with subs/sbcs and test a Z-independent condition, swapping operands for the gt/le/hi/ls cases. Also adds a standalone 32-bit icmp-to-bool lowering, which until now only existed fused into brif or select. Note that icmp's controlling type is its result type, so the rules match the operand width with value_type. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
Introduces f32/f64 on the VFP unit. regalloc2 can't model the S/D sub-register aliasing, so the float class is the D registers and an f32 lives in the low single half of its D register -- every value owns a whole D register, which also keeps the encodings uniform (F32 vs F64 is just the size bit). D0-D7 are caller-saved, D8-D15 callee-saved; moves and spills are class-aware (vmov.f64, vldr/vstr). The ABI is a simplified hard-float (args in D0-D7, return in D0). Lowers the arithmetic, negate/abs/sqrt, loads and stores, and the const materialization through GPRs. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
fcmp emits vcmp followed by vmrs to get the flags into APSR, then tests the mapped condition. fpromote/fdemote and the int<->float conversions go through vcvt (only the saturating float-to-int, matching VCVT's semantics). Bitcasts between float and integer of the same width use vmov. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
fmin/fmax reuse the trick of picking vminnm/vmaxnm when the inputs are ordered and x+y (the propagated NaN) when they aren't, which needs ARMv8. copysign is done with GPR bit twiddling on the sign bit. A scalar-float select becomes a cmp plus a conditional vmov. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
Emits a bounds check against the default target, then an add pc, pc, index, lsl into an inline table of branches. Branch26 range covers the table so no islands are needed. br_table and the call sequences are exempt from the per-instruction worst-case-size check. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
atomic_rmw and atomic_cas lower to ldaex/.../stlex retry loops emitted as single pseudo-instructions, since the register allocator can't be allowed to split the exclusive sequence. The rmw pseudo covers all of the operations; cas branches out on a mismatch. atomic_load/store use lda/stl, which give seq_cst ordering on ARMv8. Only i32 for now. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
Direct calls to a non-colocated callee had no lowering. A new LoadExtName pseudo materializes a symbol's absolute address inline (ldr rd, [pc]; b .+8; .word <sym>) with an Abs4 relocation, and a far call loads the target that way and calls it indirectly. The same helper also lowers func_addr and symbol_value. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
Threads an access size through the exclusive instructions so they encode the byte and halfword forms. Sub-word rmw needs no operand extension for the plain ops (the store truncates), but min/max and cas extend their inputs before comparing. 64-bit is trickier: ldrexd/strexd need consecutive even/odd register pairs, which regalloc2 can't express, so the paired atomics pin every operand to a fixed register the way aarch64 does. rmw uses the adds/adc/subs/sbc carry chains, with min/max selecting both halves on a Z-independent condition. Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
Member
|
Before going too too much further on this, have you seen this discussion on Zulip and/or #13815? |
Author
|
I did not see them. |
| } | ||
|
|
||
| /// `strex{b,h,d}`/`stlex{b,h,d} rd, rt, [rn]`. | ||
| fn enc_store_ex(acquire: bool, size: AtomicSize, rd: u32, rt: u32, rn: u32) -> u32 { |
There was a problem hiding this comment.
shouldn't this be release, not acquire?
Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
Subscribe to Label ActionDetailsThis issue or pull request has been labeled: "cranelift", "cranelift:area:machinst", "cranelift:meta", "isle"Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
some features aren't implemented yet.
I added file tests for my code.