;; Instruction formats. (type MInst (enum ;; A no-op of zero size. (Nop0) ;; A no-op of size two bytes. (Nop2) ;; An ALU operation with two register sources and a register destination. (AluRRR (alu_op ALUOp) (rd WritableReg) (rn Reg) (rm Reg)) ;; An ALU operation with a register source and a signed 16-bit ;; immediate source, and a separate register destination. (AluRRSImm16 (alu_op ALUOp) (rd WritableReg) (rn Reg) (imm i16)) ;; An ALU operation with a register in-/out operand and ;; a second register source. (AluRR (alu_op ALUOp) (rd WritableReg) (rm Reg)) ;; An ALU operation with a register in-/out operand and ;; a memory source. (AluRX (alu_op ALUOp) (rd WritableReg) (mem MemArg)) ;; An ALU operation with a register in-/out operand and a signed 16-bit ;; immediate source. (AluRSImm16 (alu_op ALUOp) (rd WritableReg) (imm i16)) ;; An ALU operation with a register in-/out operand and a signed 32-bit ;; immediate source. (AluRSImm32 (alu_op ALUOp) (rd WritableReg) (imm i32)) ;; An ALU operation with a register in-/out operand and an unsigned 32-bit ;; immediate source. (AluRUImm32 (alu_op ALUOp) (rd WritableReg) (imm u32)) ;; An ALU operation with a register in-/out operand and a shifted 16-bit ;; immediate source. (AluRUImm16Shifted (alu_op ALUOp) (rd WritableReg) (imm UImm16Shifted)) ;; An ALU operation with a register in-/out operand and a shifted 32-bit ;; immediate source. (AluRUImm32Shifted (alu_op ALUOp) (rd WritableReg) (imm UImm32Shifted)) ;; A multiply operation with two register sources and a register pair destination. ;; FIXME: The pair is hard-coded as %r0/%r1 because regalloc cannot handle pairs. (SMulWide (rn Reg) (rm Reg)) ;; A multiply operation with an in/out register pair, and an extra register source. ;; Only the lower half of the register pair is used as input. ;; FIXME: The pair is hard-coded as %r0/%r1 because regalloc cannot handle pairs. (UMulWide (rn Reg)) ;; A divide operation with an in/out register pair, and an extra register source. ;; Only the lower half of the register pair is used as input. ;; FIXME: The pair is hard-coded as %r0/%r1 because regalloc cannot handle pairs. (SDivMod32 (rn Reg)) (SDivMod64 (rn Reg)) ;; A divide operation with an in/out register pair, and an extra register source. ;; FIXME: The pair is hard-coded as %r0/%r1 because regalloc cannot handle pairs. (UDivMod32 (rn Reg)) (UDivMod64 (rn Reg)) ;; A FLOGR operation with a register source and a register pair destination. ;; FIXME The pair is hard-coded as %r0/%r1 because regalloc cannot handle pairs. (Flogr (rn Reg)) ;; A shift instruction with a register source, a register destination, ;; and an immediate plus an optional register as shift count. (ShiftRR (shift_op ShiftOp) (rd WritableReg) (rn Reg) (shift_imm u8) (shift_reg Reg)) ;; A rotate-then--selected-bits instruction with a register ;; in/out-operand, another register source, and three immediates. (RxSBG (op RxSBGOp) (rd WritableReg) (rn Reg) (start_bit u8) (end_bit u8) (rotate_amt i8)) ;; The test-only version of RxSBG, which does not modify any register ;; but only sets the condition code. (RxSBGTest (op RxSBGOp) (rd Reg) (rn Reg) (start_bit u8) (end_bit u8) (rotate_amt i8)) ;; An unary operation with a register source and a register destination. (UnaryRR (op UnaryOp) (rd WritableReg) (rn Reg)) ;; A compare operation with two register sources. (CmpRR (op CmpOp) (rn Reg) (rm Reg)) ;; A compare operation with a register source and a memory source. (CmpRX (op CmpOp) (rn Reg) (mem MemArg)) ;; A compare operation with a register source and a signed 16-bit ;; immediate source. (CmpRSImm16 (op CmpOp) (rn Reg) (imm i16)) ;; A compare operation with a register source and a signed 32-bit ;; immediate source. (CmpRSImm32 (op CmpOp) (rn Reg) (imm i32)) ;; A compare operation with a register source and a unsigned 32-bit ;; immediate source. (CmpRUImm32 (op CmpOp) (rn Reg) (imm u32)) ;; A compare-and-trap instruction with two register sources. (CmpTrapRR (op CmpOp) (rn Reg) (rm Reg) (cond Cond) (trap_code TrapCode)) ;; A compare-and-trap operation with a register source and a signed 16-bit ;; immediate source. (CmpTrapRSImm16 (op CmpOp) (rn Reg) (imm i16) (cond Cond) (trap_code TrapCode)) ;; A compare-and-trap operation with a register source and an unsigned 16-bit ;; immediate source. (CmpTrapRUImm16 (op CmpOp) (rn Reg) (imm u16) (cond Cond) (trap_code TrapCode)) ;; An atomic read-modify-write operation with a memory in-/out operand, ;; a register destination, and a register source. ;; a memory source. (AtomicRmw (alu_op ALUOp) (rd WritableReg) (rn Reg) (mem MemArg)) ;; A 32-bit atomic compare-and-swap operation. (AtomicCas32 (rd WritableReg) (rn Reg) (mem MemArg)) ;; A 64-bit atomic compare-and-swap operation. (AtomicCas64 (rd WritableReg) (rn Reg) (mem MemArg)) ;; A memory fence operation. (Fence) ;; A 32-bit load. (Load32 (rd WritableReg) (mem MemArg)) ;; An unsigned (zero-extending) 8-bit to 32-bit load. (Load32ZExt8 (rd WritableReg) (mem MemArg)) ;; A signed (sign-extending) 8-bit to 32-bit load. (Load32SExt8 (rd WritableReg) (mem MemArg)) ;; An unsigned (zero-extending) 16-bit to 32-bit load. (Load32ZExt16 (rd WritableReg) (mem MemArg)) ;; A signed (sign-extending) 16-bit to 32-bit load. (Load32SExt16 (rd WritableReg) (mem MemArg)) ;; A 64-bit load. (Load64 (rd WritableReg) (mem MemArg)) ;; An unsigned (zero-extending) 8-bit to 64-bit load. (Load64ZExt8 (rd WritableReg) (mem MemArg)) ;; A signed (sign-extending) 8-bit to 64-bit load. (Load64SExt8 (rd WritableReg) (mem MemArg)) ;; An unsigned (zero-extending) 16-bit to 64-bit load. (Load64ZExt16 (rd WritableReg) (mem MemArg)) ;; A signed (sign-extending) 16-bit to 64-bit load. (Load64SExt16 (rd WritableReg) (mem MemArg)) ;; An unsigned (zero-extending) 32-bit to 64-bit load. (Load64ZExt32 (rd WritableReg) (mem MemArg)) ;; A signed (sign-extending) 32-bit to 64-bit load. (Load64SExt32 (rd WritableReg) (mem MemArg)) ;; A 16-bit byte-reversed load. (LoadRev16 (rd WritableReg) (mem MemArg)) ;; A 32-bit byte-reversed load. (LoadRev32 (rd WritableReg) (mem MemArg)) ;; A 64-bit byte-reversed load. (LoadRev64 (rd WritableReg) (mem MemArg)) ;; An 8-bit store. (Store8 (rd Reg) (mem MemArg)) ;; A 16-bit store. (Store16 (rd Reg) (mem MemArg)) ;; A 32-bit store. (Store32 (rd Reg) (mem MemArg)) ;; A 64-bit store. (Store64 (rd Reg) (mem MemArg)) ;; An 8-bit store of an immediate. (StoreImm8 (imm u8) (mem MemArg)) ;; A 16-bit store of an immediate. (StoreImm16 (imm i16) (mem MemArg)) ;; A 32-bit store of a sign-extended 16-bit immediate. (StoreImm32SExt16 (imm i16) (mem MemArg)) ;; A 64-bit store of a sign-extended 16-bit immediate. (StoreImm64SExt16 (imm i16) (mem MemArg)) ;; A 16-bit byte-reversed store. (StoreRev16 (rd Reg) (mem MemArg)) ;; A 32-bit byte-reversed store. (StoreRev32 (rd Reg) (mem MemArg)) ;; A 64-bit byte-reversed store. (StoreRev64 (rd Reg) (mem MemArg)) ;; A load-multiple instruction. (LoadMultiple64 (rt WritableReg) (rt2 WritableReg) (mem MemArg)) ;; A store-multiple instruction. (StoreMultiple64 (rt Reg) (rt2 Reg) (mem MemArg)) ;; A 32-bit move instruction. (Mov32 (rd WritableReg) (rm Reg)) ;; A 64-bit move instruction. (Mov64 (rd WritableReg) (rm Reg)) ;; A 32-bit move instruction with a full 32-bit immediate. (Mov32Imm (rd WritableReg) (imm u32)) ;; A 32-bit move instruction with a 16-bit signed immediate. (Mov32SImm16 (rd WritableReg) (imm i16)) ;; A 64-bit move instruction with a 16-bit signed immediate. (Mov64SImm16 (rd WritableReg) (imm i16)) ;; A 64-bit move instruction with a 32-bit signed immediate. (Mov64SImm32 (rd WritableReg) (imm i32)) ;; A 64-bit move instruction with a shifted 16-bit immediate. (Mov64UImm16Shifted (rd WritableReg) (imm UImm16Shifted)) ;; A 64-bit move instruction with a shifted 32-bit immediate. (Mov64UImm32Shifted (rd WritableReg) (imm UImm32Shifted)) ;; A 64-bit insert instruction with a shifted 16-bit immediate. (Insert64UImm16Shifted (rd WritableReg) (imm UImm16Shifted)) ;; A 64-bit insert instruction with a shifted 32-bit immediate. (Insert64UImm32Shifted (rd WritableReg) (imm UImm32Shifted)) ;; A sign- or zero-extend operation. (Extend (rd WritableReg) (rn Reg) (signed bool) (from_bits u8) (to_bits u8)) ;; A 32-bit conditional move instruction. (CMov32 (rd WritableReg) (cond Cond) (rm Reg)) ;; A 64-bit conditional move instruction. (CMov64 (rd WritableReg) (cond Cond) (rm Reg)) ;; A 32-bit conditional move instruction with a 16-bit signed immediate. (CMov32SImm16 (rd WritableReg) (cond Cond) (imm i16)) ;; A 64-bit conditional move instruction with a 16-bit signed immediate. (CMov64SImm16 (rd WritableReg) (cond Cond) (imm i16)) ;; A 32-bit FPU move. (FpuMove32 (rd WritableReg) (rn Reg)) ;; A 64-bit FPU move. (FpuMove64 (rd WritableReg) (rn Reg)) ;; A 32-bit conditional move FPU instruction. (FpuCMov32 (rd WritableReg) (cond Cond) (rm Reg)) ;; A 64-bit conditional move FPU instruction. (FpuCMov64 (rd WritableReg) (cond Cond) (rm Reg)) ;; A 64-bit move instruction from GPR to FPR. (MovToFpr (rd WritableReg) (rn Reg)) ;; A 64-bit move instruction from FPR to GPR. (MovFromFpr (rd WritableReg) (rn Reg)) ;; 1-op FPU instruction. (FpuRR (fpu_op FPUOp1) (rd WritableReg) (rn Reg)) ;; 2-op FPU instruction. (FpuRRR (fpu_op FPUOp2) (rd WritableReg) (rm Reg)) ;; 3-op FPU instruction. (FpuRRRR (fpu_op FPUOp3) (rd WritableReg) (rn Reg) (rm Reg)) ;; FPU copy sign instruction. (FpuCopysign (rd WritableReg) (rn Reg) (rm Reg)) ;; FPU comparison, single-precision (32 bit). (FpuCmp32 (rn Reg) (rm Reg)) ;; FPU comparison, double-precision (64 bit). (FpuCmp64 (rn Reg) (rm Reg)) ;; Floating-point load, single-precision (32 bit). (FpuLoad32 (rd WritableReg) (mem MemArg)) ;; Floating-point store, single-precision (32 bit). (FpuStore32 (rd Reg) (mem MemArg)) ;; Floating-point load, double-precision (64 bit). (FpuLoad64 (rd WritableReg) (mem MemArg)) ;; Floating-point store, double-precision (64 bit). (FpuStore64 (rd Reg) (mem MemArg)) ;; Floating-point byte-reversed load, single-precision (32 bit). (FpuLoadRev32 (rd WritableReg) (mem MemArg)) ;; Floating-point byte-reversed store, single-precision (32 bit). (FpuStoreRev32 (rd Reg) (mem MemArg)) ;; Floating-point byte-reversed load, double-precision (64 bit). (FpuLoadRev64 (rd WritableReg) (mem MemArg)) ;; Floating-point byte-reversed store, double-precision (64 bit). (FpuStoreRev64 (rd Reg) (mem MemArg)) ;; Load floating-point constant, single-precision (32 bit). (LoadFpuConst32 (rd WritableReg) (const_data u32)) ;; Load floating-point constant, double-precision (64 bit). (LoadFpuConst64 (rd WritableReg) (const_data u64)) ;; Conversion FP -> integer. (FpuToInt (op FpuToIntOp) (rd WritableReg) (rn Reg)) ;; Conversion integer -> FP. (IntToFpu (op IntToFpuOp) (rd WritableReg) (rn Reg)) ;; Round to integer. (FpuRound (op FpuRoundMode) (rd WritableReg) (rn Reg)) ;; 2-op FPU instruction implemented as vector instruction with the W bit. (FpuVecRRR (fpu_op FPUOp2) (rd WritableReg) (rn Reg) (rm Reg)) ;; A machine call instruction. (Call (link WritableReg) (info BoxCallInfo)) ;; A machine indirect-call instruction. (CallInd (link WritableReg) (info BoxCallIndInfo)) ;; ---- branches (exactly one must appear at end of BB) ---- ;; A machine return instruction. (Ret (link Reg)) ;; A placeholder instruction, generating no code, meaning that a function epilogue must be ;; inserted there. (EpiloguePlaceholder) ;; An unconditional branch. (Jump (dest MachLabel)) ;; A conditional branch. Contains two targets; at emission time, both are emitted, but ;; the MachBuffer knows to truncate the trailing branch if fallthrough. We optimize the ;; choice of taken/not_taken (inverting the branch polarity as needed) based on the ;; fallthrough at the time of lowering. (CondBr (taken MachLabel) (not_taken MachLabel) (cond Cond)) ;; A conditional trap execute a `Trap` if the condition is true. This is ;; one VCode instruction because it uses embedded control flow; it is ;; logically a single-in, single-out region, but needs to appear as one ;; unit to the register allocator. ;; ;; The `Cond` gives the conditional-branch condition that will ;; *execute* the embedded `Trap`. (In the emitted code, we use the inverse ;; of this condition in a branch that skips the trap instruction.) (TrapIf (cond Cond) (trap_code TrapCode)) ;; A one-way conditional branch, invisible to the CFG processing; used *only* as part of ;; straight-line sequences in code to be emitted. ;; ;; In more detail: ;; - This branch is lowered to a branch at the machine-code level, but does not end a basic ;; block, and does not create edges in the CFG seen by regalloc. ;; - Thus, it is *only* valid to use as part of a single-in, single-out sequence that is ;; lowered from a single CLIF instruction. For example, certain arithmetic operations may ;; use these branches to handle certain conditions, such as overflows, traps, etc. ;; ;; See, e.g., the lowering of `trapif` (conditional trap) for an example. (OneWayCondBr (target MachLabel) (cond Cond)) ;; An indirect branch through a register, augmented with set of all ;; possible successors. (IndirectBr (rn Reg) (targets VecMachLabel)) ;; A "debugtrap" instruction, used for e.g. traps and debug breakpoints. (Debugtrap) ;; An instruction guaranteed to always be undefined and to trigger an illegal instruction at ;; runtime. (Trap (trap_code TrapCode)) ;; Jump-table sequence, as one compound instruction (see note in lower.rs ;; for rationale). (JTSequence (ridx Reg) (targets VecMachLabel)) ;; Load an inline symbol reference with RelocDistance::Far. (LoadExtNameFar (rd WritableReg) (name BoxExternalName) (offset i64)) ;; Load address referenced by `mem` into `rd`. (LoadAddr (rd WritableReg) (mem MemArg)) ;; Meta-instruction to emit a loop around a sequence of instructions. ;; This control flow is not visible to the compiler core, in particular ;; the register allocator. Therefore, instructions in the loop may not ;; write to any virtual register, so any writes must use reserved hard ;; registers (e.g. %r0, %r1). *Reading* virtual registers is OK. (Loop (body VecMInst) (cond Cond)) ;; Conditional branch breaking out of a loop emitted via Loop. (CondBreak (cond Cond)) ;; Marker, no-op in generated code SP "virtual offset" is adjusted. This ;; controls how MemArg::NominalSPOffset args are lowered. (VirtualSPOffsetAdj (offset i64)) ;; A definition of a value label. (ValueLabelMarker (reg Reg) (label ValueLabel)) ;; An unwind pseudoinstruction describing the state of the ;; machine at this program point. (Unwind (inst UnwindInst)) )) ;; Primitive types used in instruction formats. (type BoxCallInfo (primitive BoxCallInfo)) (type BoxCallIndInfo (primitive BoxCallIndInfo)) (type BoxJTSequenceInfo (primitive BoxJTSequenceInfo)) ;; An ALU operation. (type ALUOp (enum (Add32) (Add32Ext16) (Add64) (Add64Ext16) (Add64Ext32) (AddLogical32) (AddLogical64) (AddLogical64Ext32) (Sub32) (Sub32Ext16) (Sub64) (Sub64Ext16) (Sub64Ext32) (SubLogical32) (SubLogical64) (SubLogical64Ext32) (Mul32) (Mul32Ext16) (Mul64) (Mul64Ext16) (Mul64Ext32) (And32) (And64) (Orr32) (Orr64) (Xor32) (Xor64) ;; NAND (AndNot32) (AndNot64) ;; NOR (OrrNot32) (OrrNot64) ;; XNOR (XorNot32) (XorNot64) )) ;; A unary operation. (type UnaryOp (enum (Abs32) (Abs64) (Abs64Ext32) (Neg32) (Neg64) (Neg64Ext32) (PopcntByte) (PopcntReg) (BSwap32) (BSwap64) )) ;; A shift operation. (type ShiftOp (enum (RotL32) (RotL64) (LShL32) (LShL64) (LShR32) (LShR64) (AShR32) (AShR64) )) ;; A rotate-then--selected-bits operation. (type RxSBGOp (enum (Insert) (And) (Or) (Xor) )) ;; An integer comparison operation. (type CmpOp (enum (CmpS32) (CmpS32Ext16) (CmpS64) (CmpS64Ext16) (CmpS64Ext32) (CmpL32) (CmpL32Ext16) (CmpL64) (CmpL64Ext16) (CmpL64Ext32) )) ;; A floating-point unit (FPU) operation with one arg. (type FPUOp1 (enum (Abs32) (Abs64) (Neg32) (Neg64) (NegAbs32) (NegAbs64) (Sqrt32) (Sqrt64) (Cvt32To64) (Cvt64To32) )) ;; A floating-point unit (FPU) operation with two args. (type FPUOp2 (enum (Add32) (Add64) (Sub32) (Sub64) (Mul32) (Mul64) (Div32) (Div64) (Max32) (Max64) (Min32) (Min64) )) ;; A floating-point unit (FPU) operation with three args. (type FPUOp3 (enum (MAdd32) (MAdd64) (MSub32) (MSub64) )) ;; A conversion from an FP to an integer value. (type FpuToIntOp (enum (F32ToU32) (F32ToI32) (F32ToU64) (F32ToI64) (F64ToU32) (F64ToI32) (F64ToU64) (F64ToI64) )) ;; A conversion from an integer to an FP value. (type IntToFpuOp (enum (U32ToF32) (I32ToF32) (U32ToF64) (I32ToF64) (U64ToF32) (I64ToF32) (U64ToF64) (I64ToF64) )) ;; Modes for FP rounding ops: round down (floor) or up (ceil), or toward zero ;; (trunc), or to nearest, and for 32- or 64-bit FP values. (type FpuRoundMode (enum (Minus32) (Minus64) (Plus32) (Plus64) (Zero32) (Zero64) (Nearest32) (Nearest64) )) ;; Helpers for querying enabled ISA extensions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (decl mie2_enabled () Type) (extern extractor mie2_enabled mie2_enabled) (decl mie2_disabled () Type) (extern extractor mie2_disabled mie2_disabled) (decl vxrs_ext2_enabled () Type) (extern extractor vxrs_ext2_enabled vxrs_ext2_enabled) (decl vxrs_ext2_disabled () Type) (extern extractor vxrs_ext2_disabled vxrs_ext2_disabled) (decl allow_div_traps () Type) (extern extractor allow_div_traps allow_div_traps) ;; Helpers for register numbers and types ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Hard-coded registers. (decl writable_gpr (u8) WritableReg) (extern constructor writable_gpr writable_gpr) ;; The zero register. (decl zero_reg () Reg) (extern constructor zero_reg zero_reg) ;; Types that can be operated on using 32-bit GPR instructions (decl gpr32_ty (Type) Type) (extern extractor gpr32_ty gpr32_ty) ;; Types that can be operated on using 64-bit GPR instructions (decl gpr64_ty (Type) Type) (extern extractor gpr64_ty gpr64_ty) ;; Helpers for various immmediate constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Special integer types and their constructors (type UImm32Shifted (primitive UImm32Shifted)) (decl uimm32shifted (u32 u8) UImm32Shifted) (extern constructor uimm32shifted uimm32shifted) (type UImm16Shifted (primitive UImm16Shifted)) (decl uimm16shifted (u16 u8) UImm16Shifted) (extern constructor uimm16shifted uimm16shifted) ;; Detect specific integer values (decl i64_nonequal (i64 i64) i64) (extern extractor i64_nonequal i64_nonequal (out in)) (decl i64_nonzero (i64) i64) (extractor (i64_nonzero val) (i64_nonequal val <0)) (decl i64_not_neg1 (i64) i64) (extractor (i64_not_neg1 val) (i64_nonequal val <-1)) ;; Integer type casts (with the rust `as` semantics). (decl u8_as_u16 (u8) u16) (extern constructor u8_as_u16 u8_as_u16) (decl u64_as_u32 (u64) u32) (extern constructor u64_as_u32 u64_as_u32) (decl u64_as_i16 (u64) i16) (extern constructor u64_as_i16 u64_as_i16) ;; Split an u64 into high and low parts. (decl u64_nonzero_hipart (u64) u64) (extern extractor u64_nonzero_hipart u64_nonzero_hipart) (decl u64_nonzero_lopart (u64) u64) (extern extractor u64_nonzero_lopart u64_nonzero_lopart) ;; Extract smaller integer type from u64 if it matches. (decl i32_from_u64 (i32) u64) (extern extractor i32_from_u64 i32_from_u64) (decl i16_from_u64 (i16) u64) (extern extractor i16_from_u64 i16_from_u64) (decl uimm32shifted_from_u64 (UImm32Shifted) u64) (extern extractor uimm32shifted_from_u64 uimm32shifted_from_u64) (decl uimm16shifted_from_u64 (UImm16Shifted) u64) (extern extractor uimm16shifted_from_u64 uimm16shifted_from_u64) ;; Extract integer of certain type from value if it matches. (decl u64_from_value (u64) Value) (extern extractor u64_from_value u64_from_value) (decl u32_from_value (u32) Value) (extern extractor u32_from_value u32_from_value) (decl u8_from_value (u8) Value) (extern extractor u8_from_value u8_from_value) (decl u64_from_signed_value (u64) Value) (extern extractor u64_from_signed_value u64_from_signed_value) (decl i64_from_value (i64) Value) (extern extractor i64_from_value i64_from_value) (decl i32_from_value (i32) Value) (extern extractor i32_from_value i32_from_value) (decl i16_from_value (i16) Value) (extern extractor i16_from_value i16_from_value) (decl i16_from_swapped_value (i16) Value) (extern extractor i16_from_swapped_value i16_from_swapped_value) (decl i64_from_negated_value (i64) Value) (extern extractor i64_from_negated_value i64_from_negated_value) (decl i32_from_negated_value (i32) Value) (extern extractor i32_from_negated_value i32_from_negated_value) (decl i16_from_negated_value (i16) Value) (extern extractor i16_from_negated_value i16_from_negated_value) (decl uimm16shifted_from_value (UImm16Shifted) Value) (extern extractor uimm16shifted_from_value uimm16shifted_from_value) (decl uimm32shifted_from_value (UImm32Shifted) Value) (extern extractor uimm32shifted_from_value uimm32shifted_from_value) (decl uimm16shifted_from_inverted_value (UImm16Shifted) Value) (extern extractor uimm16shifted_from_inverted_value uimm16shifted_from_inverted_value) (decl uimm32shifted_from_inverted_value (UImm32Shifted) Value) (extern extractor uimm32shifted_from_inverted_value uimm32shifted_from_inverted_value) ;; Helpers for masking shift amounts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Mask (immediate) shift amount to the type size. (decl mask_amt_imm (Type i64) u8) (extern constructor mask_amt_imm mask_amt_imm) ;; Mask (immediate) shift amount to the type size. ;; Note that the hardware instructions always masks to six bits, so ;; in the case of a 64-bit type we do not need any explicit masking. (decl mask_amt_reg (Type Reg) Reg) (rule (mask_amt_reg (gpr32_ty ty) reg) (let ((mask u8 (mask_amt_imm ty -1))) (and_uimm16shifted ty reg (uimm16shifted (u8_as_u16 mask) 0)))) (rule (mask_amt_reg (gpr64_ty ty) reg) reg) ;; Helpers for condition codes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (type Cond extern (enum)) (decl mask_as_cond (u8) Cond) (extern constructor mask_as_cond mask_as_cond) (decl intcc_as_cond (IntCC) Cond) (extern constructor intcc_as_cond intcc_as_cond) (decl floatcc_as_cond (FloatCC) Cond) (extern constructor floatcc_as_cond floatcc_as_cond) (decl invert_cond (Cond) Cond) (extern constructor invert_cond invert_cond) (decl signed () IntCC) (extern extractor signed signed) (decl unsigned () IntCC) (extern extractor unsigned unsigned) ;; Helpers for machine label vectors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (decl vec_length_minus1 (VecMachLabel) u32) (extern constructor vec_length_minus1 vec_length_minus1) (decl vec_element (VecMachLabel u8) MachLabel) (extern constructor vec_element vec_element) ;; Helpers for memory arguments ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Accessors for `Offset32`. (decl zero_offset () Offset32) (extern constructor zero_offset zero_offset) (decl i64_from_offset (i64) Offset32) (extern extractor infallible i64_from_offset i64_from_offset) ;; Accessors for `ExternalName`. (decl box_external_name (ExternalName) BoxExternalName) (extern constructor box_external_name box_external_name) ;; Accessors for `MemFlags`. (decl littleendian () MemFlags) (extern extractor littleendian littleendian) (decl bigendian () MemFlags) (extern extractor bigendian bigendian) (decl memflags_trusted () MemFlags) (extern constructor memflags_trusted memflags_trusted) ;; Accessors for `MemArg`. (type MemArg extern (enum)) (decl memarg_reg_plus_reg (Reg Reg MemFlags) MemArg) (extern constructor memarg_reg_plus_reg memarg_reg_plus_reg) (decl memarg_reg_plus_off (Reg i64 MemFlags) MemArg) (extern constructor memarg_reg_plus_off memarg_reg_plus_off) (decl memarg_symbol (ExternalName i32 MemFlags) MemArg) (extern constructor memarg_symbol memarg_symbol) ;; Form the sum of two offset values, and check that the result is ;; a valid `MemArg::Symbol` offset (i.e. is even and fits into i32). (decl memarg_symbol_offset_sum (i64 i32) i64) (extern extractor memarg_symbol_offset_sum memarg_symbol_offset_sum (in out)) ;; Likewise, but just check a single offset value. (decl memarg_symbol_offset (i32) i64) (extractor (memarg_symbol_offset offset) (memarg_symbol_offset_sum <0 offset)) ;; Lower an address into a `MemArg`. (decl lower_address (MemFlags Value Offset32) MemArg) (rule (lower_address flags addr (i64_from_offset offset)) (memarg_reg_plus_off addr offset flags)) (rule (lower_address flags (def_inst (iadd x y)) (i64_from_offset 0)) (memarg_reg_plus_reg x y flags)) (rule (lower_address flags (def_inst (symbol_value (symbol_value_data name (reloc_distance_near) offset))) (i64_from_offset (memarg_symbol_offset_sum