Uncovered by @bjorn3 (thanks!): 8- and 16-bit rotates were not working properly in recent versions of Cranelift with part of the lowering migrated to ISLE. This PR fixes a few issues: - 8- and 16-bit rotate-left needs to mask a constant amount, if any, because we use a 32-bit rotate instruction and so don't get the appropriate shift-amount masking for free from x86 semantics. - `operand_size_from_type` was incorrect: it only handled 32- and 64-bit types and silently returned `OperandSize::Size32` for everything else. Now uses the `OperandSize::from_ty(ty)` helper as the pre-ISLE code did. Our test coverage for narrow value types is not great; this PR adds some runtests for rotl/rotr but more would always be better!
4151 lines
182 KiB
Rust
Generated
4151 lines
182 KiB
Rust
Generated
// GENERATED BY ISLE. DO NOT EDIT!
|
|
//
|
|
// Generated automatically from the instruction-selection DSL code in:
|
|
// - src/clif.isle
|
|
// - src/prelude.isle
|
|
// - src/isa/aarch64/inst.isle
|
|
// - src/isa/aarch64/lower.isle
|
|
|
|
#![allow(dead_code, unreachable_code, unreachable_patterns)]
|
|
#![allow(unused_imports, unused_variables, non_snake_case)]
|
|
#![allow(irrefutable_let_patterns)]
|
|
|
|
use super::*; // Pulls in all external types.
|
|
|
|
/// Context during lowering: an implementation of this trait
|
|
/// must be provided with all external constructors and extractors.
|
|
/// A mutable borrow is passed along through all lowering logic.
|
|
pub trait Context {
|
|
fn unpack_value_array_2(&mut self, arg0: &ValueArray2) -> (Value, Value);
|
|
fn pack_value_array_2(&mut self, arg0: Value, arg1: Value) -> ValueArray2;
|
|
fn unpack_value_array_3(&mut self, arg0: &ValueArray3) -> (Value, Value, Value);
|
|
fn pack_value_array_3(&mut self, arg0: Value, arg1: Value, arg2: Value) -> ValueArray3;
|
|
fn value_reg(&mut self, arg0: Reg) -> ValueRegs;
|
|
fn value_regs(&mut self, arg0: Reg, arg1: Reg) -> ValueRegs;
|
|
fn temp_writable_reg(&mut self, arg0: Type) -> WritableReg;
|
|
fn invalid_reg(&mut self) -> Reg;
|
|
fn put_in_reg(&mut self, arg0: Value) -> Reg;
|
|
fn put_in_regs(&mut self, arg0: Value) -> ValueRegs;
|
|
fn value_regs_get(&mut self, arg0: ValueRegs, arg1: usize) -> Reg;
|
|
fn u8_as_u64(&mut self, arg0: u8) -> u64;
|
|
fn u16_as_u64(&mut self, arg0: u16) -> u64;
|
|
fn u32_as_u64(&mut self, arg0: u32) -> u64;
|
|
fn ty_bits(&mut self, arg0: Type) -> u8;
|
|
fn ty_bits_u16(&mut self, arg0: Type) -> u16;
|
|
fn fits_in_32(&mut self, arg0: Type) -> Option<Type>;
|
|
fn fits_in_64(&mut self, arg0: Type) -> Option<Type>;
|
|
fn ty_32_or_64(&mut self, arg0: Type) -> Option<Type>;
|
|
fn ty_8_or_16(&mut self, arg0: Type) -> Option<Type>;
|
|
fn vec128(&mut self, arg0: Type) -> Option<Type>;
|
|
fn not_i64x2(&mut self, arg0: Type) -> Option<()>;
|
|
fn value_list_slice(&mut self, arg0: ValueList) -> ValueSlice;
|
|
fn unwrap_head_value_list_1(&mut self, arg0: ValueList) -> (Value, ValueSlice);
|
|
fn unwrap_head_value_list_2(&mut self, arg0: ValueList) -> (Value, Value, ValueSlice);
|
|
fn writable_reg_to_reg(&mut self, arg0: WritableReg) -> Reg;
|
|
fn u8_from_uimm8(&mut self, arg0: Uimm8) -> u8;
|
|
fn u64_from_imm64(&mut self, arg0: Imm64) -> u64;
|
|
fn nonzero_u64_from_imm64(&mut self, arg0: Imm64) -> Option<u64>;
|
|
fn u64_from_ieee32(&mut self, arg0: Ieee32) -> u64;
|
|
fn u64_from_ieee64(&mut self, arg0: Ieee64) -> u64;
|
|
fn inst_results(&mut self, arg0: Inst) -> ValueSlice;
|
|
fn first_result(&mut self, arg0: Inst) -> Option<Value>;
|
|
fn inst_data(&mut self, arg0: Inst) -> InstructionData;
|
|
fn value_type(&mut self, arg0: Value) -> Type;
|
|
fn ty_bits_mask(&mut self, arg0: Type) -> u64;
|
|
fn multi_lane(&mut self, arg0: Type) -> Option<(u8, u16)>;
|
|
fn def_inst(&mut self, arg0: Value) -> Option<Inst>;
|
|
fn trap_code_division_by_zero(&mut self) -> TrapCode;
|
|
fn trap_code_integer_overflow(&mut self) -> TrapCode;
|
|
fn move_wide_const_from_u64(&mut self, arg0: u64) -> Option<MoveWideConst>;
|
|
fn move_wide_const_from_negated_u64(&mut self, arg0: u64) -> Option<MoveWideConst>;
|
|
fn imm_logic_from_u64(&mut self, arg0: u64, arg1: Type) -> Option<ImmLogic>;
|
|
fn imm_logic_from_imm64(&mut self, arg0: Imm64, arg1: Type) -> Option<ImmLogic>;
|
|
fn imm_shift_from_u8(&mut self, arg0: u8) -> ImmShift;
|
|
fn imm12_from_u64(&mut self, arg0: u64) -> Option<Imm12>;
|
|
fn u8_into_uimm5(&mut self, arg0: u8) -> UImm5;
|
|
fn u8_into_imm12(&mut self, arg0: u8) -> Imm12;
|
|
fn imm12_from_negated_u64(&mut self, arg0: u64) -> Option<Imm12>;
|
|
fn lshl_from_imm64(&mut self, arg0: Imm64, arg1: Type) -> Option<ShiftOpAndAmt>;
|
|
fn integral_ty(&mut self, arg0: Type) -> Option<Type>;
|
|
fn extended_value_from_value(&mut self, arg0: Value) -> Option<ExtendedValue>;
|
|
fn put_extended_in_reg(&mut self, arg0: &ExtendedValue) -> Reg;
|
|
fn get_extended_op(&mut self, arg0: &ExtendedValue) -> ExtendOp;
|
|
fn nzcv(&mut self, arg0: bool, arg1: bool, arg2: bool, arg3: bool) -> NZCV;
|
|
fn cond_br_zero(&mut self, arg0: Reg) -> CondBrKind;
|
|
fn cond_br_cond(&mut self, arg0: &Cond) -> CondBrKind;
|
|
fn emit(&mut self, arg0: &MInst) -> Unit;
|
|
fn zero_reg(&mut self) -> Reg;
|
|
fn writable_zero_reg(&mut self) -> WritableReg;
|
|
fn load_constant64_full(&mut self, arg0: u64) -> Reg;
|
|
fn sinkable_atomic_load(&mut self, arg0: Value) -> Option<SinkableAtomicLoad>;
|
|
fn sink_atomic_load(&mut self, arg0: &SinkableAtomicLoad) -> Reg;
|
|
fn safe_divisor_from_imm64(&mut self, arg0: Imm64) -> Option<u64>;
|
|
}
|
|
|
|
/// Internal type ProducesFlags: defined at src/prelude.isle line 259.
|
|
#[derive(Clone, Debug)]
|
|
pub enum ProducesFlags {
|
|
ProducesFlags { inst: MInst, result: Reg },
|
|
}
|
|
|
|
/// Internal type ConsumesFlags: defined at src/prelude.isle line 262.
|
|
#[derive(Clone, Debug)]
|
|
pub enum ConsumesFlags {
|
|
ConsumesFlags { inst: MInst, result: Reg },
|
|
}
|
|
|
|
/// Internal type MInst: defined at src/isa/aarch64/inst.isle line 2.
|
|
#[derive(Clone, Debug)]
|
|
pub enum MInst {
|
|
Nop0,
|
|
Nop4,
|
|
AluRRR {
|
|
alu_op: ALUOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
rm: Reg,
|
|
},
|
|
AluRRRR {
|
|
alu_op: ALUOp3,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
rm: Reg,
|
|
ra: Reg,
|
|
},
|
|
AluRRImm12 {
|
|
alu_op: ALUOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
imm12: Imm12,
|
|
},
|
|
AluRRImmLogic {
|
|
alu_op: ALUOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
imml: ImmLogic,
|
|
},
|
|
AluRRImmShift {
|
|
alu_op: ALUOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
immshift: ImmShift,
|
|
},
|
|
AluRRRShift {
|
|
alu_op: ALUOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
rm: Reg,
|
|
shiftop: ShiftOpAndAmt,
|
|
},
|
|
AluRRRExtend {
|
|
alu_op: ALUOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
rm: Reg,
|
|
extendop: ExtendOp,
|
|
},
|
|
BitRR {
|
|
op: BitOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
},
|
|
ULoad8 {
|
|
rd: WritableReg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
SLoad8 {
|
|
rd: WritableReg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
ULoad16 {
|
|
rd: WritableReg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
SLoad16 {
|
|
rd: WritableReg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
ULoad32 {
|
|
rd: WritableReg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
SLoad32 {
|
|
rd: WritableReg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
ULoad64 {
|
|
rd: WritableReg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
Store8 {
|
|
rd: Reg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
Store16 {
|
|
rd: Reg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
Store32 {
|
|
rd: Reg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
Store64 {
|
|
rd: Reg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
StoreP64 {
|
|
rt: Reg,
|
|
rt2: Reg,
|
|
mem: PairAMode,
|
|
flags: MemFlags,
|
|
},
|
|
LoadP64 {
|
|
rt: WritableReg,
|
|
rt2: WritableReg,
|
|
mem: PairAMode,
|
|
flags: MemFlags,
|
|
},
|
|
Mov64 {
|
|
rd: WritableReg,
|
|
rm: Reg,
|
|
},
|
|
Mov32 {
|
|
rd: WritableReg,
|
|
rm: Reg,
|
|
},
|
|
MovZ {
|
|
rd: WritableReg,
|
|
imm: MoveWideConst,
|
|
size: OperandSize,
|
|
},
|
|
MovN {
|
|
rd: WritableReg,
|
|
imm: MoveWideConst,
|
|
size: OperandSize,
|
|
},
|
|
MovK {
|
|
rd: WritableReg,
|
|
imm: MoveWideConst,
|
|
size: OperandSize,
|
|
},
|
|
Extend {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
signed: bool,
|
|
from_bits: u8,
|
|
to_bits: u8,
|
|
},
|
|
CSel {
|
|
rd: WritableReg,
|
|
cond: Cond,
|
|
rn: Reg,
|
|
rm: Reg,
|
|
},
|
|
CSet {
|
|
rd: WritableReg,
|
|
cond: Cond,
|
|
},
|
|
CSetm {
|
|
rd: WritableReg,
|
|
cond: Cond,
|
|
},
|
|
CCmpImm {
|
|
size: OperandSize,
|
|
rn: Reg,
|
|
imm: UImm5,
|
|
nzcv: NZCV,
|
|
cond: Cond,
|
|
},
|
|
AtomicRMWLoop {
|
|
ty: Type,
|
|
op: AtomicRmwOp,
|
|
},
|
|
AtomicRMW {
|
|
op: AtomicRMWOp,
|
|
rs: Reg,
|
|
rt: WritableReg,
|
|
rn: Reg,
|
|
ty: Type,
|
|
},
|
|
AtomicCAS {
|
|
rs: WritableReg,
|
|
rt: Reg,
|
|
rn: Reg,
|
|
ty: Type,
|
|
},
|
|
AtomicCASLoop {
|
|
ty: Type,
|
|
},
|
|
LoadAcquire {
|
|
access_ty: Type,
|
|
rt: WritableReg,
|
|
rn: Reg,
|
|
},
|
|
StoreRelease {
|
|
access_ty: Type,
|
|
rt: Reg,
|
|
rn: Reg,
|
|
},
|
|
Fence,
|
|
FpuMove64 {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
},
|
|
FpuMove128 {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
},
|
|
FpuMoveFromVec {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
idx: u8,
|
|
size: VectorSize,
|
|
},
|
|
FpuExtend {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
size: ScalarSize,
|
|
},
|
|
FpuRR {
|
|
fpu_op: FPUOp1,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
},
|
|
FpuRRR {
|
|
fpu_op: FPUOp2,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
rm: Reg,
|
|
},
|
|
FpuRRI {
|
|
fpu_op: FPUOpRI,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
},
|
|
FpuRRRR {
|
|
fpu_op: FPUOp3,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
rm: Reg,
|
|
ra: Reg,
|
|
},
|
|
FpuCmp32 {
|
|
rn: Reg,
|
|
rm: Reg,
|
|
},
|
|
FpuCmp64 {
|
|
rn: Reg,
|
|
rm: Reg,
|
|
},
|
|
FpuLoad32 {
|
|
rd: WritableReg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
FpuStore32 {
|
|
rd: Reg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
FpuLoad64 {
|
|
rd: WritableReg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
FpuStore64 {
|
|
rd: Reg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
FpuLoad128 {
|
|
rd: WritableReg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
FpuStore128 {
|
|
rd: Reg,
|
|
mem: AMode,
|
|
flags: MemFlags,
|
|
},
|
|
FpuLoadP64 {
|
|
rt: WritableReg,
|
|
rt2: WritableReg,
|
|
mem: PairAMode,
|
|
flags: MemFlags,
|
|
},
|
|
FpuStoreP64 {
|
|
rt: Reg,
|
|
rt2: Reg,
|
|
mem: PairAMode,
|
|
flags: MemFlags,
|
|
},
|
|
FpuLoadP128 {
|
|
rt: WritableReg,
|
|
rt2: WritableReg,
|
|
mem: PairAMode,
|
|
flags: MemFlags,
|
|
},
|
|
FpuStoreP128 {
|
|
rt: Reg,
|
|
rt2: Reg,
|
|
mem: PairAMode,
|
|
flags: MemFlags,
|
|
},
|
|
LoadFpuConst64 {
|
|
rd: WritableReg,
|
|
const_data: u64,
|
|
},
|
|
LoadFpuConst128 {
|
|
rd: WritableReg,
|
|
const_data: u128,
|
|
},
|
|
FpuToInt {
|
|
op: FpuToIntOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
},
|
|
IntToFpu {
|
|
op: IntToFpuOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
},
|
|
FpuCSel32 {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
rm: Reg,
|
|
cond: Cond,
|
|
},
|
|
FpuCSel64 {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
rm: Reg,
|
|
cond: Cond,
|
|
},
|
|
FpuRound {
|
|
op: FpuRoundMode,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
},
|
|
MovToFpu {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
size: ScalarSize,
|
|
},
|
|
MovToVec {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
idx: u8,
|
|
size: VectorSize,
|
|
},
|
|
MovFromVec {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
idx: u8,
|
|
size: VectorSize,
|
|
},
|
|
MovFromVecSigned {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
idx: u8,
|
|
size: VectorSize,
|
|
scalar_size: OperandSize,
|
|
},
|
|
VecDup {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
size: VectorSize,
|
|
},
|
|
VecDupFromFpu {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
size: VectorSize,
|
|
},
|
|
VecDupFPImm {
|
|
rd: WritableReg,
|
|
imm: ASIMDFPModImm,
|
|
size: VectorSize,
|
|
},
|
|
VecDupImm {
|
|
rd: WritableReg,
|
|
imm: ASIMDMovModImm,
|
|
invert: bool,
|
|
size: VectorSize,
|
|
},
|
|
VecExtend {
|
|
t: VecExtendOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
high_half: bool,
|
|
},
|
|
VecMovElement {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
dest_idx: u8,
|
|
src_idx: u8,
|
|
size: VectorSize,
|
|
},
|
|
VecRRLong {
|
|
op: VecRRLongOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
high_half: bool,
|
|
},
|
|
VecRRNarrow {
|
|
op: VecRRNarrowOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
high_half: bool,
|
|
},
|
|
VecRRPair {
|
|
op: VecPairOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
},
|
|
VecRRRLong {
|
|
alu_op: VecRRRLongOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
rm: Reg,
|
|
high_half: bool,
|
|
},
|
|
VecRRPairLong {
|
|
op: VecRRPairLongOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
},
|
|
VecRRR {
|
|
alu_op: VecALUOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
rm: Reg,
|
|
size: VectorSize,
|
|
},
|
|
VecMisc {
|
|
op: VecMisc2,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
size: VectorSize,
|
|
},
|
|
VecLanes {
|
|
op: VecLanesOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
size: VectorSize,
|
|
},
|
|
VecShiftImm {
|
|
op: VecShiftImmOp,
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
size: VectorSize,
|
|
imm: u8,
|
|
},
|
|
VecExtract {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
rm: Reg,
|
|
imm4: u8,
|
|
},
|
|
VecTbl {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
rm: Reg,
|
|
is_extension: bool,
|
|
},
|
|
VecTbl2 {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
rn2: Reg,
|
|
rm: Reg,
|
|
is_extension: bool,
|
|
},
|
|
VecLoadReplicate {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
size: VectorSize,
|
|
},
|
|
VecCSel {
|
|
rd: WritableReg,
|
|
rn: Reg,
|
|
rm: Reg,
|
|
cond: Cond,
|
|
},
|
|
MovToNZCV {
|
|
rn: Reg,
|
|
},
|
|
MovFromNZCV {
|
|
rd: WritableReg,
|
|
},
|
|
Call {
|
|
info: BoxCallInfo,
|
|
},
|
|
CallInd {
|
|
info: BoxCallIndInfo,
|
|
},
|
|
Ret,
|
|
EpiloguePlaceholder,
|
|
Jump {
|
|
dest: BranchTarget,
|
|
},
|
|
CondBr {
|
|
taken: BranchTarget,
|
|
not_taken: BranchTarget,
|
|
kind: CondBrKind,
|
|
},
|
|
TrapIf {
|
|
kind: CondBrKind,
|
|
trap_code: TrapCode,
|
|
},
|
|
IndirectBr {
|
|
rn: Reg,
|
|
targets: VecMachLabel,
|
|
},
|
|
Brk,
|
|
Udf {
|
|
trap_code: TrapCode,
|
|
},
|
|
Adr {
|
|
rd: WritableReg,
|
|
off: i32,
|
|
},
|
|
Word4 {
|
|
data: u32,
|
|
},
|
|
Word8 {
|
|
data: u64,
|
|
},
|
|
JTSequence {
|
|
info: BoxJTSequenceInfo,
|
|
ridx: Reg,
|
|
rtmp1: WritableReg,
|
|
rtmp2: WritableReg,
|
|
},
|
|
LoadExtName {
|
|
rd: WritableReg,
|
|
name: BoxExternalName,
|
|
offset: i64,
|
|
},
|
|
LoadAddr {
|
|
rd: WritableReg,
|
|
mem: AMode,
|
|
},
|
|
VirtualSPOffsetAdj {
|
|
offset: i64,
|
|
},
|
|
EmitIsland {
|
|
needed_space: CodeOffset,
|
|
},
|
|
ElfTlsGetAddr {
|
|
symbol: ExternalName,
|
|
},
|
|
ValueLabelMarker {
|
|
reg: Reg,
|
|
label: ValueLabel,
|
|
},
|
|
Unwind {
|
|
inst: UnwindInst,
|
|
},
|
|
}
|
|
|
|
/// Internal type ALUOp: defined at src/isa/aarch64/inst.isle line 783.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum ALUOp {
|
|
Add32,
|
|
Add64,
|
|
Sub32,
|
|
Sub64,
|
|
Orr32,
|
|
Orr64,
|
|
OrrNot32,
|
|
OrrNot64,
|
|
And32,
|
|
And64,
|
|
AndS32,
|
|
AndS64,
|
|
AndNot32,
|
|
AndNot64,
|
|
Eor32,
|
|
Eor64,
|
|
EorNot32,
|
|
EorNot64,
|
|
AddS32,
|
|
AddS64,
|
|
SubS32,
|
|
SubS64,
|
|
SMulH,
|
|
UMulH,
|
|
SDiv64,
|
|
UDiv64,
|
|
RotR32,
|
|
RotR64,
|
|
Lsr32,
|
|
Lsr64,
|
|
Asr32,
|
|
Asr64,
|
|
Lsl32,
|
|
Lsl64,
|
|
Adc32,
|
|
Adc64,
|
|
AdcS32,
|
|
AdcS64,
|
|
Sbc32,
|
|
Sbc64,
|
|
SbcS32,
|
|
SbcS64,
|
|
}
|
|
|
|
/// Internal type ALUOp3: defined at src/isa/aarch64/inst.isle line 844.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum ALUOp3 {
|
|
MAdd32,
|
|
MAdd64,
|
|
MSub32,
|
|
MSub64,
|
|
}
|
|
|
|
/// Internal type BitOp: defined at src/isa/aarch64/inst.isle line 892.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum BitOp {
|
|
RBit32,
|
|
RBit64,
|
|
Clz32,
|
|
Clz64,
|
|
Cls32,
|
|
Cls64,
|
|
}
|
|
|
|
/// Internal type FPUOp1: defined at src/isa/aarch64/inst.isle line 958.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum FPUOp1 {
|
|
Abs32,
|
|
Abs64,
|
|
Neg32,
|
|
Neg64,
|
|
Sqrt32,
|
|
Sqrt64,
|
|
Cvt32To64,
|
|
Cvt64To32,
|
|
}
|
|
|
|
/// Internal type FPUOp2: defined at src/isa/aarch64/inst.isle line 971.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum FPUOp2 {
|
|
Add32,
|
|
Add64,
|
|
Sub32,
|
|
Sub64,
|
|
Mul32,
|
|
Mul64,
|
|
Div32,
|
|
Div64,
|
|
Max32,
|
|
Max64,
|
|
Min32,
|
|
Min64,
|
|
Sqadd64,
|
|
Uqadd64,
|
|
Sqsub64,
|
|
Uqsub64,
|
|
}
|
|
|
|
/// Internal type FPUOp3: defined at src/isa/aarch64/inst.isle line 996.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum FPUOp3 {
|
|
MAdd32,
|
|
MAdd64,
|
|
}
|
|
|
|
/// Internal type FpuToIntOp: defined at src/isa/aarch64/inst.isle line 1003.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum FpuToIntOp {
|
|
F32ToU32,
|
|
F32ToI32,
|
|
F32ToU64,
|
|
F32ToI64,
|
|
F64ToU32,
|
|
F64ToI32,
|
|
F64ToU64,
|
|
F64ToI64,
|
|
}
|
|
|
|
/// Internal type IntToFpuOp: defined at src/isa/aarch64/inst.isle line 1016.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum IntToFpuOp {
|
|
U32ToF32,
|
|
I32ToF32,
|
|
U32ToF64,
|
|
I32ToF64,
|
|
U64ToF32,
|
|
I64ToF32,
|
|
U64ToF64,
|
|
I64ToF64,
|
|
}
|
|
|
|
/// Internal type FpuRoundMode: defined at src/isa/aarch64/inst.isle line 1030.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum FpuRoundMode {
|
|
Minus32,
|
|
Minus64,
|
|
Plus32,
|
|
Plus64,
|
|
Zero32,
|
|
Zero64,
|
|
Nearest32,
|
|
Nearest64,
|
|
}
|
|
|
|
/// Internal type VecExtendOp: defined at src/isa/aarch64/inst.isle line 1043.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum VecExtendOp {
|
|
Sxtl8,
|
|
Sxtl16,
|
|
Sxtl32,
|
|
Uxtl8,
|
|
Uxtl16,
|
|
Uxtl32,
|
|
}
|
|
|
|
/// Internal type VecALUOp: defined at src/isa/aarch64/inst.isle line 1060.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum VecALUOp {
|
|
Sqadd,
|
|
Uqadd,
|
|
Sqsub,
|
|
Uqsub,
|
|
Cmeq,
|
|
Cmge,
|
|
Cmgt,
|
|
Cmhs,
|
|
Cmhi,
|
|
Fcmeq,
|
|
Fcmgt,
|
|
Fcmge,
|
|
And,
|
|
Bic,
|
|
Orr,
|
|
Eor,
|
|
Bsl,
|
|
Umaxp,
|
|
Add,
|
|
Sub,
|
|
Mul,
|
|
Sshl,
|
|
Ushl,
|
|
Umin,
|
|
Smin,
|
|
Umax,
|
|
Smax,
|
|
Urhadd,
|
|
Fadd,
|
|
Fsub,
|
|
Fdiv,
|
|
Fmax,
|
|
Fmin,
|
|
Fmul,
|
|
Addp,
|
|
Zip1,
|
|
Sqrdmulh,
|
|
}
|
|
|
|
/// Internal type VecMisc2: defined at src/isa/aarch64/inst.isle line 1139.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum VecMisc2 {
|
|
Not,
|
|
Neg,
|
|
Abs,
|
|
Fabs,
|
|
Fneg,
|
|
Fsqrt,
|
|
Rev64,
|
|
Fcvtzs,
|
|
Fcvtzu,
|
|
Scvtf,
|
|
Ucvtf,
|
|
Frintn,
|
|
Frintz,
|
|
Frintm,
|
|
Frintp,
|
|
Cnt,
|
|
Cmeq0,
|
|
}
|
|
|
|
/// Internal type VecRRLongOp: defined at src/isa/aarch64/inst.isle line 1178.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum VecRRLongOp {
|
|
Fcvtl16,
|
|
Fcvtl32,
|
|
Shll8,
|
|
Shll16,
|
|
Shll32,
|
|
}
|
|
|
|
/// Internal type VecRRNarrowOp: defined at src/isa/aarch64/inst.isle line 1193.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum VecRRNarrowOp {
|
|
Xtn16,
|
|
Xtn32,
|
|
Xtn64,
|
|
Sqxtn16,
|
|
Sqxtn32,
|
|
Sqxtn64,
|
|
Sqxtun16,
|
|
Sqxtun32,
|
|
Sqxtun64,
|
|
Uqxtn16,
|
|
Uqxtn32,
|
|
Uqxtn64,
|
|
Fcvtn32,
|
|
Fcvtn64,
|
|
}
|
|
|
|
/// Internal type VecRRRLongOp: defined at src/isa/aarch64/inst.isle line 1225.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum VecRRRLongOp {
|
|
Smull8,
|
|
Smull16,
|
|
Smull32,
|
|
Umull8,
|
|
Umull16,
|
|
Umull32,
|
|
Umlal8,
|
|
Umlal16,
|
|
Umlal32,
|
|
}
|
|
|
|
/// Internal type VecPairOp: defined at src/isa/aarch64/inst.isle line 1242.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum VecPairOp {
|
|
Addp,
|
|
}
|
|
|
|
/// Internal type VecRRPairLongOp: defined at src/isa/aarch64/inst.isle line 1250.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum VecRRPairLongOp {
|
|
Saddlp8,
|
|
Saddlp16,
|
|
Uaddlp8,
|
|
Uaddlp16,
|
|
}
|
|
|
|
/// Internal type VecLanesOp: defined at src/isa/aarch64/inst.isle line 1261.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum VecLanesOp {
|
|
Addv,
|
|
Uminv,
|
|
}
|
|
|
|
/// Internal type VecShiftImmOp: defined at src/isa/aarch64/inst.isle line 1270.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum VecShiftImmOp {
|
|
Shl,
|
|
Ushr,
|
|
Sshr,
|
|
}
|
|
|
|
/// Internal type AtomicRMWOp: defined at src/isa/aarch64/inst.isle line 1281.
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum AtomicRMWOp {
|
|
Add,
|
|
Clr,
|
|
Eor,
|
|
Set,
|
|
Smax,
|
|
Smin,
|
|
Umax,
|
|
Umin,
|
|
}
|
|
|
|
// Generated as internal constructor for term temp_reg.
|
|
pub fn constructor_temp_reg<C: Context>(ctx: &mut C, arg0: Type) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
// Rule at src/prelude.isle line 60.
|
|
let expr0_0 = C::temp_writable_reg(ctx, pattern0_0);
|
|
let expr1_0 = C::writable_reg_to_reg(ctx, expr0_0);
|
|
return Some(expr1_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term lo_reg.
|
|
pub fn constructor_lo_reg<C: Context>(ctx: &mut C, arg0: Value) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
// Rule at src/prelude.isle line 95.
|
|
let expr0_0 = C::put_in_regs(ctx, pattern0_0);
|
|
let expr1_0: usize = 0;
|
|
let expr2_0 = C::value_regs_get(ctx, expr0_0, expr1_0);
|
|
return Some(expr2_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term with_flags.
|
|
pub fn constructor_with_flags<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &ProducesFlags,
|
|
arg1: &ConsumesFlags,
|
|
) -> Option<ValueRegs> {
|
|
let pattern0_0 = arg0;
|
|
if let &ProducesFlags::ProducesFlags {
|
|
inst: ref pattern1_0,
|
|
result: pattern1_1,
|
|
} = pattern0_0
|
|
{
|
|
let pattern2_0 = arg1;
|
|
if let &ConsumesFlags::ConsumesFlags {
|
|
inst: ref pattern3_0,
|
|
result: pattern3_1,
|
|
} = pattern2_0
|
|
{
|
|
// Rule at src/prelude.isle line 272.
|
|
let expr0_0 = C::emit(ctx, &pattern1_0);
|
|
let expr1_0 = C::emit(ctx, &pattern3_0);
|
|
let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1);
|
|
return Some(expr2_0);
|
|
}
|
|
}
|
|
return None;
|
|
}
|
|
|
|
// Generated as internal constructor for term with_flags_1.
|
|
pub fn constructor_with_flags_1<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &ProducesFlags,
|
|
arg1: &ConsumesFlags,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
if let &ProducesFlags::ProducesFlags {
|
|
inst: ref pattern1_0,
|
|
result: pattern1_1,
|
|
} = pattern0_0
|
|
{
|
|
let pattern2_0 = arg1;
|
|
if let &ConsumesFlags::ConsumesFlags {
|
|
inst: ref pattern3_0,
|
|
result: pattern3_1,
|
|
} = pattern2_0
|
|
{
|
|
// Rule at src/prelude.isle line 280.
|
|
let expr0_0 = C::emit(ctx, &pattern1_0);
|
|
let expr1_0 = C::emit(ctx, &pattern3_0);
|
|
return Some(pattern3_1);
|
|
}
|
|
}
|
|
return None;
|
|
}
|
|
|
|
// Generated as internal constructor for term with_flags_2.
|
|
pub fn constructor_with_flags_2<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &ProducesFlags,
|
|
arg1: &ConsumesFlags,
|
|
arg2: &ConsumesFlags,
|
|
) -> Option<ValueRegs> {
|
|
let pattern0_0 = arg0;
|
|
if let &ProducesFlags::ProducesFlags {
|
|
inst: ref pattern1_0,
|
|
result: pattern1_1,
|
|
} = pattern0_0
|
|
{
|
|
let pattern2_0 = arg1;
|
|
if let &ConsumesFlags::ConsumesFlags {
|
|
inst: ref pattern3_0,
|
|
result: pattern3_1,
|
|
} = pattern2_0
|
|
{
|
|
let pattern4_0 = arg2;
|
|
if let &ConsumesFlags::ConsumesFlags {
|
|
inst: ref pattern5_0,
|
|
result: pattern5_1,
|
|
} = pattern4_0
|
|
{
|
|
// Rule at src/prelude.isle line 290.
|
|
let expr0_0 = C::emit(ctx, &pattern1_0);
|
|
let expr1_0 = C::emit(ctx, &pattern3_0);
|
|
let expr2_0 = C::emit(ctx, &pattern5_0);
|
|
let expr3_0 = C::value_regs(ctx, pattern3_1, pattern5_1);
|
|
return Some(expr3_0);
|
|
}
|
|
}
|
|
}
|
|
return None;
|
|
}
|
|
|
|
// Generated as internal constructor for term vector_size.
|
|
pub fn constructor_vector_size<C: Context>(ctx: &mut C, arg0: Type) -> Option<VectorSize> {
|
|
let pattern0_0 = arg0;
|
|
if let Some((pattern1_0, pattern1_1)) = C::multi_lane(ctx, pattern0_0) {
|
|
if pattern1_0 == 8 {
|
|
if pattern1_1 == 16 {
|
|
// Rule at src/isa/aarch64/inst.isle line 952.
|
|
let expr0_0 = VectorSize::Size8x16;
|
|
return Some(expr0_0);
|
|
}
|
|
}
|
|
if pattern1_0 == 16 {
|
|
if pattern1_1 == 8 {
|
|
// Rule at src/isa/aarch64/inst.isle line 953.
|
|
let expr0_0 = VectorSize::Size16x8;
|
|
return Some(expr0_0);
|
|
}
|
|
}
|
|
if pattern1_0 == 32 {
|
|
if pattern1_1 == 4 {
|
|
// Rule at src/isa/aarch64/inst.isle line 954.
|
|
let expr0_0 = VectorSize::Size32x4;
|
|
return Some(expr0_0);
|
|
}
|
|
}
|
|
if pattern1_0 == 64 {
|
|
if pattern1_1 == 2 {
|
|
// Rule at src/isa/aarch64/inst.isle line 955.
|
|
let expr0_0 = VectorSize::Size64x2;
|
|
return Some(expr0_0);
|
|
}
|
|
}
|
|
}
|
|
return None;
|
|
}
|
|
|
|
// Generated as internal constructor for term movz.
|
|
pub fn constructor_movz<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: MoveWideConst,
|
|
arg1: &OperandSize,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
// Rule at src/isa/aarch64/inst.isle line 1378.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::MovZ {
|
|
rd: expr1_0,
|
|
imm: pattern0_0,
|
|
size: pattern1_0.clone(),
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term movn.
|
|
pub fn constructor_movn<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: MoveWideConst,
|
|
arg1: &OperandSize,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
// Rule at src/isa/aarch64/inst.isle line 1385.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::MovN {
|
|
rd: expr1_0,
|
|
imm: pattern0_0,
|
|
size: pattern1_0.clone(),
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term alu_rr_imm_logic.
|
|
pub fn constructor_alu_rr_imm_logic<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &ALUOp,
|
|
arg1: Reg,
|
|
arg2: ImmLogic,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
// Rule at src/isa/aarch64/inst.isle line 1392.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::AluRRImmLogic {
|
|
alu_op: pattern0_0.clone(),
|
|
rd: expr1_0,
|
|
rn: pattern1_0,
|
|
imml: pattern2_0,
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term alu_rr_imm_shift.
|
|
pub fn constructor_alu_rr_imm_shift<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &ALUOp,
|
|
arg1: Reg,
|
|
arg2: ImmShift,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
// Rule at src/isa/aarch64/inst.isle line 1399.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::AluRRImmShift {
|
|
alu_op: pattern0_0.clone(),
|
|
rd: expr1_0,
|
|
rn: pattern1_0,
|
|
immshift: pattern2_0,
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term alu_rrr.
|
|
pub fn constructor_alu_rrr<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &ALUOp,
|
|
arg1: Reg,
|
|
arg2: Reg,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
// Rule at src/isa/aarch64/inst.isle line 1406.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::AluRRR {
|
|
alu_op: pattern0_0.clone(),
|
|
rd: expr1_0,
|
|
rn: pattern1_0,
|
|
rm: pattern2_0,
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term vec_rrr.
|
|
pub fn constructor_vec_rrr<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &VecALUOp,
|
|
arg1: Reg,
|
|
arg2: Reg,
|
|
arg3: &VectorSize,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
let pattern3_0 = arg3;
|
|
// Rule at src/isa/aarch64/inst.isle line 1413.
|
|
let expr0_0: Type = I8X16;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::VecRRR {
|
|
alu_op: pattern0_0.clone(),
|
|
rd: expr1_0,
|
|
rn: pattern1_0,
|
|
rm: pattern2_0,
|
|
size: pattern3_0.clone(),
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term alu_rr_imm12.
|
|
pub fn constructor_alu_rr_imm12<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &ALUOp,
|
|
arg1: Reg,
|
|
arg2: Imm12,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
// Rule at src/isa/aarch64/inst.isle line 1420.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::AluRRImm12 {
|
|
alu_op: pattern0_0.clone(),
|
|
rd: expr1_0,
|
|
rn: pattern1_0,
|
|
imm12: pattern2_0,
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term alu_rrr_shift.
|
|
pub fn constructor_alu_rrr_shift<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &ALUOp,
|
|
arg1: Reg,
|
|
arg2: Reg,
|
|
arg3: ShiftOpAndAmt,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
let pattern3_0 = arg3;
|
|
// Rule at src/isa/aarch64/inst.isle line 1427.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::AluRRRShift {
|
|
alu_op: pattern0_0.clone(),
|
|
rd: expr1_0,
|
|
rn: pattern1_0,
|
|
rm: pattern2_0,
|
|
shiftop: pattern3_0,
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term alu_rrr_extend.
|
|
pub fn constructor_alu_rrr_extend<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &ALUOp,
|
|
arg1: Reg,
|
|
arg2: Reg,
|
|
arg3: &ExtendOp,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
let pattern3_0 = arg3;
|
|
// Rule at src/isa/aarch64/inst.isle line 1434.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::AluRRRExtend {
|
|
alu_op: pattern0_0.clone(),
|
|
rd: expr1_0,
|
|
rn: pattern1_0,
|
|
rm: pattern2_0,
|
|
extendop: pattern3_0.clone(),
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term alu_rr_extend_reg.
|
|
pub fn constructor_alu_rr_extend_reg<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &ALUOp,
|
|
arg1: Reg,
|
|
arg2: &ExtendedValue,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
// Rule at src/isa/aarch64/inst.isle line 1442.
|
|
let expr0_0 = C::put_extended_in_reg(ctx, pattern2_0);
|
|
let expr1_0 = C::get_extended_op(ctx, pattern2_0);
|
|
let expr2_0 = constructor_alu_rrr_extend(ctx, pattern0_0, pattern1_0, expr0_0, &expr1_0)?;
|
|
return Some(expr2_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term alu_rrrr.
|
|
pub fn constructor_alu_rrrr<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &ALUOp3,
|
|
arg1: Reg,
|
|
arg2: Reg,
|
|
arg3: Reg,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
let pattern3_0 = arg3;
|
|
// Rule at src/isa/aarch64/inst.isle line 1449.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::AluRRRR {
|
|
alu_op: pattern0_0.clone(),
|
|
rd: expr1_0,
|
|
rn: pattern1_0,
|
|
rm: pattern2_0,
|
|
ra: pattern3_0,
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term add64_with_flags.
|
|
pub fn constructor_add64_with_flags<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: Reg,
|
|
arg1: Reg,
|
|
) -> Option<ProducesFlags> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
// Rule at src/isa/aarch64/inst.isle line 1456.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = ALUOp::AddS64;
|
|
let expr3_0 = MInst::AluRRR {
|
|
alu_op: expr2_0,
|
|
rd: expr1_0,
|
|
rn: pattern0_0,
|
|
rm: pattern1_0,
|
|
};
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
let expr5_0 = ProducesFlags::ProducesFlags {
|
|
inst: expr3_0,
|
|
result: expr4_0,
|
|
};
|
|
return Some(expr5_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term adc64.
|
|
pub fn constructor_adc64<C: Context>(ctx: &mut C, arg0: Reg, arg1: Reg) -> Option<ConsumesFlags> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
// Rule at src/isa/aarch64/inst.isle line 1463.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = ALUOp::Adc64;
|
|
let expr3_0 = MInst::AluRRR {
|
|
alu_op: expr2_0,
|
|
rd: expr1_0,
|
|
rn: pattern0_0,
|
|
rm: pattern1_0,
|
|
};
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
let expr5_0 = ConsumesFlags::ConsumesFlags {
|
|
inst: expr3_0,
|
|
result: expr4_0,
|
|
};
|
|
return Some(expr5_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term sub64_with_flags.
|
|
pub fn constructor_sub64_with_flags<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: Reg,
|
|
arg1: Reg,
|
|
) -> Option<ProducesFlags> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
// Rule at src/isa/aarch64/inst.isle line 1470.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = ALUOp::SubS64;
|
|
let expr3_0 = MInst::AluRRR {
|
|
alu_op: expr2_0,
|
|
rd: expr1_0,
|
|
rn: pattern0_0,
|
|
rm: pattern1_0,
|
|
};
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
let expr5_0 = ProducesFlags::ProducesFlags {
|
|
inst: expr3_0,
|
|
result: expr4_0,
|
|
};
|
|
return Some(expr5_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term sbc64.
|
|
pub fn constructor_sbc64<C: Context>(ctx: &mut C, arg0: Reg, arg1: Reg) -> Option<ConsumesFlags> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
// Rule at src/isa/aarch64/inst.isle line 1477.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = ALUOp::Sbc64;
|
|
let expr3_0 = MInst::AluRRR {
|
|
alu_op: expr2_0,
|
|
rd: expr1_0,
|
|
rn: pattern0_0,
|
|
rm: pattern1_0,
|
|
};
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
let expr5_0 = ConsumesFlags::ConsumesFlags {
|
|
inst: expr3_0,
|
|
result: expr4_0,
|
|
};
|
|
return Some(expr5_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term vec_misc.
|
|
pub fn constructor_vec_misc<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &VecMisc2,
|
|
arg1: Reg,
|
|
arg2: &VectorSize,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
// Rule at src/isa/aarch64/inst.isle line 1484.
|
|
let expr0_0: Type = I8X16;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::VecMisc {
|
|
op: pattern0_0.clone(),
|
|
rd: expr1_0,
|
|
rn: pattern1_0,
|
|
size: pattern2_0.clone(),
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term vec_rrr_long.
|
|
pub fn constructor_vec_rrr_long<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &VecRRRLongOp,
|
|
arg1: Reg,
|
|
arg2: Reg,
|
|
arg3: bool,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
let pattern3_0 = arg3;
|
|
// Rule at src/isa/aarch64/inst.isle line 1491.
|
|
let expr0_0: Type = I8X16;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::VecRRRLong {
|
|
alu_op: pattern0_0.clone(),
|
|
rd: expr1_0,
|
|
rn: pattern1_0,
|
|
rm: pattern2_0,
|
|
high_half: pattern3_0,
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term vec_rrrr_long.
|
|
pub fn constructor_vec_rrrr_long<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &VecRRRLongOp,
|
|
arg1: Reg,
|
|
arg2: Reg,
|
|
arg3: Reg,
|
|
arg4: bool,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
let pattern3_0 = arg3;
|
|
let pattern4_0 = arg4;
|
|
// Rule at src/isa/aarch64/inst.isle line 1501.
|
|
let expr0_0: Type = I8X16;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::FpuMove128 {
|
|
rd: expr1_0,
|
|
rn: pattern1_0,
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = MInst::VecRRRLong {
|
|
alu_op: pattern0_0.clone(),
|
|
rd: expr1_0,
|
|
rn: pattern2_0,
|
|
rm: pattern3_0,
|
|
high_half: pattern4_0,
|
|
};
|
|
let expr5_0 = C::emit(ctx, &expr4_0);
|
|
let expr6_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr6_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term vec_rr_narrow.
|
|
pub fn constructor_vec_rr_narrow<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &VecRRNarrowOp,
|
|
arg1: Reg,
|
|
arg2: bool,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
// Rule at src/isa/aarch64/inst.isle line 1509.
|
|
let expr0_0: Type = I8X16;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::VecRRNarrow {
|
|
op: pattern0_0.clone(),
|
|
rd: expr1_0,
|
|
rn: pattern1_0,
|
|
high_half: pattern2_0,
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term vec_rr_long.
|
|
pub fn constructor_vec_rr_long<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &VecRRLongOp,
|
|
arg1: Reg,
|
|
arg2: bool,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
// Rule at src/isa/aarch64/inst.isle line 1516.
|
|
let expr0_0: Type = I8X16;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::VecRRLong {
|
|
op: pattern0_0.clone(),
|
|
rd: expr1_0,
|
|
rn: pattern1_0,
|
|
high_half: pattern2_0,
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term mov_from_vec.
|
|
pub fn constructor_mov_from_vec<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: Reg,
|
|
arg1: u8,
|
|
arg2: &VectorSize,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
// Rule at src/isa/aarch64/inst.isle line 1523.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::MovFromVec {
|
|
rd: expr1_0,
|
|
rn: pattern0_0,
|
|
idx: pattern1_0,
|
|
size: pattern2_0.clone(),
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term mov_from_vec_signed.
|
|
pub fn constructor_mov_from_vec_signed<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: Reg,
|
|
arg1: u8,
|
|
arg2: &VectorSize,
|
|
arg3: &OperandSize,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
let pattern3_0 = arg3;
|
|
// Rule at src/isa/aarch64/inst.isle line 1530.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::MovFromVecSigned {
|
|
rd: expr1_0,
|
|
rn: pattern0_0,
|
|
idx: pattern1_0,
|
|
size: pattern2_0.clone(),
|
|
scalar_size: pattern3_0.clone(),
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term extend.
|
|
pub fn constructor_extend<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: Reg,
|
|
arg1: bool,
|
|
arg2: u8,
|
|
arg3: u8,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
let pattern3_0 = arg3;
|
|
// Rule at src/isa/aarch64/inst.isle line 1537.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::Extend {
|
|
rd: expr1_0,
|
|
rn: pattern0_0,
|
|
signed: pattern1_0,
|
|
from_bits: pattern2_0,
|
|
to_bits: pattern3_0,
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term load_acquire.
|
|
pub fn constructor_load_acquire<C: Context>(ctx: &mut C, arg0: Type, arg1: Reg) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
// Rule at src/isa/aarch64/inst.isle line 1544.
|
|
let expr0_0: Type = I64;
|
|
let expr1_0 = C::temp_writable_reg(ctx, expr0_0);
|
|
let expr2_0 = MInst::LoadAcquire {
|
|
access_ty: pattern0_0,
|
|
rt: expr1_0,
|
|
rn: pattern1_0,
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
let expr4_0 = C::writable_reg_to_reg(ctx, expr1_0);
|
|
return Some(expr4_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term imm.
|
|
pub fn constructor_imm<C: Context>(ctx: &mut C, arg0: Type, arg1: u64) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
if let Some(pattern1_0) = C::integral_ty(ctx, pattern0_0) {
|
|
let pattern2_0 = arg1;
|
|
let closure3 = || {
|
|
let expr0_0: Type = I64;
|
|
return Some(expr0_0);
|
|
};
|
|
if let Some(pattern3_0) = closure3() {
|
|
if let Some(pattern4_0) = C::imm_logic_from_u64(ctx, pattern2_0, pattern3_0) {
|
|
// Rule at src/isa/aarch64/inst.isle line 1562.
|
|
let expr0_0 = ALUOp::Orr64;
|
|
let expr1_0 = C::zero_reg(ctx);
|
|
let expr2_0 = constructor_alu_rr_imm_logic(ctx, &expr0_0, expr1_0, pattern4_0)?;
|
|
return Some(expr2_0);
|
|
}
|
|
}
|
|
if let Some(pattern3_0) = C::move_wide_const_from_u64(ctx, pattern2_0) {
|
|
// Rule at src/isa/aarch64/inst.isle line 1554.
|
|
let expr0_0 = OperandSize::Size64;
|
|
let expr1_0 = constructor_movz(ctx, pattern3_0, &expr0_0)?;
|
|
return Some(expr1_0);
|
|
}
|
|
if let Some(pattern3_0) = C::move_wide_const_from_negated_u64(ctx, pattern2_0) {
|
|
// Rule at src/isa/aarch64/inst.isle line 1558.
|
|
let expr0_0 = OperandSize::Size64;
|
|
let expr1_0 = constructor_movn(ctx, pattern3_0, &expr0_0)?;
|
|
return Some(expr1_0);
|
|
}
|
|
// Rule at src/isa/aarch64/inst.isle line 1569.
|
|
let expr0_0 = C::load_constant64_full(ctx, pattern2_0);
|
|
return Some(expr0_0);
|
|
}
|
|
return None;
|
|
}
|
|
|
|
// Generated as internal constructor for term put_in_reg_sext64.
|
|
pub fn constructor_put_in_reg_sext64<C: Context>(ctx: &mut C, arg0: Value) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = C::value_type(ctx, pattern0_0);
|
|
if pattern1_0 == I64 {
|
|
// Rule at src/isa/aarch64/inst.isle line 1580.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern0_0);
|
|
return Some(expr0_0);
|
|
}
|
|
if let Some(pattern2_0) = C::fits_in_32(ctx, pattern1_0) {
|
|
// Rule at src/isa/aarch64/inst.isle line 1576.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern0_0);
|
|
let expr1_0: bool = true;
|
|
let expr2_0 = C::ty_bits(ctx, pattern2_0);
|
|
let expr3_0: u8 = 64;
|
|
let expr4_0 = constructor_extend(ctx, expr0_0, expr1_0, expr2_0, expr3_0)?;
|
|
return Some(expr4_0);
|
|
}
|
|
return None;
|
|
}
|
|
|
|
// Generated as internal constructor for term put_in_reg_zext64.
|
|
pub fn constructor_put_in_reg_zext64<C: Context>(ctx: &mut C, arg0: Value) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = C::value_type(ctx, pattern0_0);
|
|
if pattern1_0 == I64 {
|
|
// Rule at src/isa/aarch64/inst.isle line 1588.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern0_0);
|
|
return Some(expr0_0);
|
|
}
|
|
if let Some(pattern2_0) = C::fits_in_32(ctx, pattern1_0) {
|
|
// Rule at src/isa/aarch64/inst.isle line 1584.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern0_0);
|
|
let expr1_0: bool = false;
|
|
let expr2_0 = C::ty_bits(ctx, pattern2_0);
|
|
let expr3_0: u8 = 64;
|
|
let expr4_0 = constructor_extend(ctx, expr0_0, expr1_0, expr2_0, expr3_0)?;
|
|
return Some(expr4_0);
|
|
}
|
|
return None;
|
|
}
|
|
|
|
// Generated as internal constructor for term trap_if_zero_divisor.
|
|
pub fn constructor_trap_if_zero_divisor<C: Context>(ctx: &mut C, arg0: Reg) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
// Rule at src/isa/aarch64/inst.isle line 1593.
|
|
let expr0_0 = C::cond_br_zero(ctx, pattern0_0);
|
|
let expr1_0 = C::trap_code_division_by_zero(ctx);
|
|
let expr2_0 = MInst::TrapIf {
|
|
kind: expr0_0,
|
|
trap_code: expr1_0,
|
|
};
|
|
let expr3_0 = C::emit(ctx, &expr2_0);
|
|
return Some(pattern0_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term size_from_ty.
|
|
pub fn constructor_size_from_ty<C: Context>(ctx: &mut C, arg0: Type) -> Option<OperandSize> {
|
|
let pattern0_0 = arg0;
|
|
if pattern0_0 == I64 {
|
|
// Rule at src/isa/aarch64/inst.isle line 1599.
|
|
let expr0_0 = OperandSize::Size64;
|
|
return Some(expr0_0);
|
|
}
|
|
if let Some(pattern1_0) = C::fits_in_32(ctx, pattern0_0) {
|
|
// Rule at src/isa/aarch64/inst.isle line 1598.
|
|
let expr0_0 = OperandSize::Size32;
|
|
return Some(expr0_0);
|
|
}
|
|
return None;
|
|
}
|
|
|
|
// Generated as internal constructor for term trap_if_div_overflow.
|
|
pub fn constructor_trap_if_div_overflow<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: Type,
|
|
arg1: Reg,
|
|
arg2: Reg,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
// Rule at src/isa/aarch64/inst.isle line 1605.
|
|
let expr0_0 = constructor_adds_op(ctx, pattern0_0)?;
|
|
let expr1_0 = C::writable_zero_reg(ctx);
|
|
let expr2_0: u8 = 1;
|
|
let expr3_0 = C::u8_into_imm12(ctx, expr2_0);
|
|
let expr4_0 = MInst::AluRRImm12 {
|
|
alu_op: expr0_0,
|
|
rd: expr1_0,
|
|
rn: pattern2_0,
|
|
imm12: expr3_0,
|
|
};
|
|
let expr5_0 = C::emit(ctx, &expr4_0);
|
|
let expr6_0 = constructor_size_from_ty(ctx, pattern0_0)?;
|
|
let expr7_0: u8 = 1;
|
|
let expr8_0 = C::u8_into_uimm5(ctx, expr7_0);
|
|
let expr9_0: bool = false;
|
|
let expr10_0: bool = false;
|
|
let expr11_0: bool = false;
|
|
let expr12_0: bool = false;
|
|
let expr13_0 = C::nzcv(ctx, expr9_0, expr10_0, expr11_0, expr12_0);
|
|
let expr14_0 = Cond::Eq;
|
|
let expr15_0 = MInst::CCmpImm {
|
|
size: expr6_0,
|
|
rn: pattern1_0,
|
|
imm: expr8_0,
|
|
nzcv: expr13_0,
|
|
cond: expr14_0,
|
|
};
|
|
let expr16_0 = C::emit(ctx, &expr15_0);
|
|
let expr17_0 = Cond::Vs;
|
|
let expr18_0 = C::cond_br_cond(ctx, &expr17_0);
|
|
let expr19_0 = C::trap_code_integer_overflow(ctx);
|
|
let expr20_0 = MInst::TrapIf {
|
|
kind: expr18_0,
|
|
trap_code: expr19_0,
|
|
};
|
|
let expr21_0 = C::emit(ctx, &expr20_0);
|
|
return Some(pattern1_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term adds_op.
|
|
pub fn constructor_adds_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<ALUOp> {
|
|
let pattern0_0 = arg0;
|
|
if pattern0_0 == I64 {
|
|
// Rule at src/isa/aarch64/inst.isle line 1625.
|
|
let expr0_0 = ALUOp::AddS64;
|
|
return Some(expr0_0);
|
|
}
|
|
if let Some(pattern1_0) = C::fits_in_32(ctx, pattern0_0) {
|
|
// Rule at src/isa/aarch64/inst.isle line 1624.
|
|
let expr0_0 = ALUOp::AddS32;
|
|
return Some(expr0_0);
|
|
}
|
|
return None;
|
|
}
|
|
|
|
// Generated as internal constructor for term alu_rs_imm_logic_commutative.
|
|
pub fn constructor_alu_rs_imm_logic_commutative<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &ALUOp,
|
|
arg1: Type,
|
|
arg2: Value,
|
|
arg3: Value,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
if let Some(pattern3_0) = C::def_inst(ctx, pattern2_0) {
|
|
let pattern4_0 = C::inst_data(ctx, pattern3_0);
|
|
match &pattern4_0 {
|
|
&InstructionData::UnaryImm {
|
|
opcode: ref pattern5_0,
|
|
imm: pattern5_1,
|
|
} => {
|
|
if let &Opcode::Iconst = &pattern5_0 {
|
|
let closure7 = || {
|
|
return Some(pattern1_0);
|
|
};
|
|
if let Some(pattern7_0) = closure7() {
|
|
if let Some(pattern8_0) =
|
|
C::imm_logic_from_imm64(ctx, pattern5_1, pattern7_0)
|
|
{
|
|
let pattern9_0 = arg3;
|
|
// Rule at src/isa/aarch64/inst.isle line 1655.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern9_0);
|
|
let expr1_0 =
|
|
constructor_alu_rr_imm_logic(ctx, pattern0_0, expr0_0, pattern8_0)?;
|
|
return Some(expr1_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
&InstructionData::Binary {
|
|
opcode: ref pattern5_0,
|
|
args: ref pattern5_1,
|
|
} => {
|
|
if let &Opcode::Ishl = &pattern5_0 {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
if let Some(pattern8_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern9_0 = C::inst_data(ctx, pattern8_0);
|
|
if let &InstructionData::UnaryImm {
|
|
opcode: ref pattern10_0,
|
|
imm: pattern10_1,
|
|
} = &pattern9_0
|
|
{
|
|
if let &Opcode::Iconst = &pattern10_0 {
|
|
let closure12 = || {
|
|
return Some(pattern1_0);
|
|
};
|
|
if let Some(pattern12_0) = closure12() {
|
|
if let Some(pattern13_0) =
|
|
C::lshl_from_imm64(ctx, pattern10_1, pattern12_0)
|
|
{
|
|
let pattern14_0 = arg3;
|
|
// Rule at src/isa/aarch64/inst.isle line 1661.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern14_0);
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = constructor_alu_rrr_shift(
|
|
ctx,
|
|
pattern0_0,
|
|
expr0_0,
|
|
expr1_0,
|
|
pattern13_0,
|
|
)?;
|
|
return Some(expr2_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
let pattern3_0 = arg3;
|
|
if let Some(pattern4_0) = C::def_inst(ctx, pattern3_0) {
|
|
let pattern5_0 = C::inst_data(ctx, pattern4_0);
|
|
match &pattern5_0 {
|
|
&InstructionData::UnaryImm {
|
|
opcode: ref pattern6_0,
|
|
imm: pattern6_1,
|
|
} => {
|
|
if let &Opcode::Iconst = &pattern6_0 {
|
|
let closure8 = || {
|
|
return Some(pattern1_0);
|
|
};
|
|
if let Some(pattern8_0) = closure8() {
|
|
if let Some(pattern9_0) =
|
|
C::imm_logic_from_imm64(ctx, pattern6_1, pattern8_0)
|
|
{
|
|
// Rule at src/isa/aarch64/inst.isle line 1653.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern2_0);
|
|
let expr1_0 =
|
|
constructor_alu_rr_imm_logic(ctx, pattern0_0, expr0_0, pattern9_0)?;
|
|
return Some(expr1_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
&InstructionData::Binary {
|
|
opcode: ref pattern6_0,
|
|
args: ref pattern6_1,
|
|
} => {
|
|
if let &Opcode::Ishl = &pattern6_0 {
|
|
let (pattern8_0, pattern8_1) = C::unpack_value_array_2(ctx, &pattern6_1);
|
|
if let Some(pattern9_0) = C::def_inst(ctx, pattern8_1) {
|
|
let pattern10_0 = C::inst_data(ctx, pattern9_0);
|
|
if let &InstructionData::UnaryImm {
|
|
opcode: ref pattern11_0,
|
|
imm: pattern11_1,
|
|
} = &pattern10_0
|
|
{
|
|
if let &Opcode::Iconst = &pattern11_0 {
|
|
let closure13 = || {
|
|
return Some(pattern1_0);
|
|
};
|
|
if let Some(pattern13_0) = closure13() {
|
|
if let Some(pattern14_0) =
|
|
C::lshl_from_imm64(ctx, pattern11_1, pattern13_0)
|
|
{
|
|
// Rule at src/isa/aarch64/inst.isle line 1659.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern2_0);
|
|
let expr1_0 = C::put_in_reg(ctx, pattern8_0);
|
|
let expr2_0 = constructor_alu_rrr_shift(
|
|
ctx,
|
|
pattern0_0,
|
|
expr0_0,
|
|
expr1_0,
|
|
pattern14_0,
|
|
)?;
|
|
return Some(expr2_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
// Rule at src/isa/aarch64/inst.isle line 1649.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern2_0);
|
|
let expr1_0 = C::put_in_reg(ctx, pattern3_0);
|
|
let expr2_0 = constructor_alu_rrr(ctx, pattern0_0, expr0_0, expr1_0)?;
|
|
return Some(expr2_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term alu_rs_imm_logic.
|
|
pub fn constructor_alu_rs_imm_logic<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &ALUOp,
|
|
arg1: Type,
|
|
arg2: Value,
|
|
arg3: Value,
|
|
) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
let pattern3_0 = arg3;
|
|
if let Some(pattern4_0) = C::def_inst(ctx, pattern3_0) {
|
|
let pattern5_0 = C::inst_data(ctx, pattern4_0);
|
|
match &pattern5_0 {
|
|
&InstructionData::UnaryImm {
|
|
opcode: ref pattern6_0,
|
|
imm: pattern6_1,
|
|
} => {
|
|
if let &Opcode::Iconst = &pattern6_0 {
|
|
let closure8 = || {
|
|
return Some(pattern1_0);
|
|
};
|
|
if let Some(pattern8_0) = closure8() {
|
|
if let Some(pattern9_0) =
|
|
C::imm_logic_from_imm64(ctx, pattern6_1, pattern8_0)
|
|
{
|
|
// Rule at src/isa/aarch64/inst.isle line 1669.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern2_0);
|
|
let expr1_0 =
|
|
constructor_alu_rr_imm_logic(ctx, pattern0_0, expr0_0, pattern9_0)?;
|
|
return Some(expr1_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
&InstructionData::Binary {
|
|
opcode: ref pattern6_0,
|
|
args: ref pattern6_1,
|
|
} => {
|
|
if let &Opcode::Ishl = &pattern6_0 {
|
|
let (pattern8_0, pattern8_1) = C::unpack_value_array_2(ctx, &pattern6_1);
|
|
if let Some(pattern9_0) = C::def_inst(ctx, pattern8_1) {
|
|
let pattern10_0 = C::inst_data(ctx, pattern9_0);
|
|
if let &InstructionData::UnaryImm {
|
|
opcode: ref pattern11_0,
|
|
imm: pattern11_1,
|
|
} = &pattern10_0
|
|
{
|
|
if let &Opcode::Iconst = &pattern11_0 {
|
|
let closure13 = || {
|
|
return Some(pattern1_0);
|
|
};
|
|
if let Some(pattern13_0) = closure13() {
|
|
if let Some(pattern14_0) =
|
|
C::lshl_from_imm64(ctx, pattern11_1, pattern13_0)
|
|
{
|
|
// Rule at src/isa/aarch64/inst.isle line 1671.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern2_0);
|
|
let expr1_0 = C::put_in_reg(ctx, pattern8_0);
|
|
let expr2_0 = constructor_alu_rrr_shift(
|
|
ctx,
|
|
pattern0_0,
|
|
expr0_0,
|
|
expr1_0,
|
|
pattern14_0,
|
|
)?;
|
|
return Some(expr2_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
// Rule at src/isa/aarch64/inst.isle line 1667.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern2_0);
|
|
let expr1_0 = C::put_in_reg(ctx, pattern3_0);
|
|
let expr2_0 = constructor_alu_rrr(ctx, pattern0_0, expr0_0, expr1_0)?;
|
|
return Some(expr2_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term i128_alu_bitop.
|
|
pub fn constructor_i128_alu_bitop<C: Context>(
|
|
ctx: &mut C,
|
|
arg0: &ALUOp,
|
|
arg1: Value,
|
|
arg2: Value,
|
|
) -> Option<ValueRegs> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = arg1;
|
|
let pattern2_0 = arg2;
|
|
// Rule at src/isa/aarch64/inst.isle line 1679.
|
|
let expr0_0 = C::put_in_regs(ctx, pattern1_0);
|
|
let expr1_0: usize = 0;
|
|
let expr2_0 = C::value_regs_get(ctx, expr0_0, expr1_0);
|
|
let expr3_0: usize = 1;
|
|
let expr4_0 = C::value_regs_get(ctx, expr0_0, expr3_0);
|
|
let expr5_0 = C::put_in_regs(ctx, pattern2_0);
|
|
let expr6_0: usize = 0;
|
|
let expr7_0 = C::value_regs_get(ctx, expr5_0, expr6_0);
|
|
let expr8_0: usize = 1;
|
|
let expr9_0 = C::value_regs_get(ctx, expr5_0, expr8_0);
|
|
let expr10_0 = constructor_alu_rrr(ctx, pattern0_0, expr2_0, expr7_0)?;
|
|
let expr11_0 = constructor_alu_rrr(ctx, pattern0_0, expr4_0, expr9_0)?;
|
|
let expr12_0 = C::value_regs(ctx, expr10_0, expr11_0);
|
|
return Some(expr12_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term lower.
|
|
pub fn constructor_lower<C: Context>(ctx: &mut C, arg0: Inst) -> Option<ValueRegs> {
|
|
let pattern0_0 = arg0;
|
|
if let Some(pattern1_0) = C::first_result(ctx, pattern0_0) {
|
|
let pattern2_0 = C::value_type(ctx, pattern1_0);
|
|
if pattern2_0 == I64 {
|
|
let pattern4_0 = C::inst_data(ctx, pattern0_0);
|
|
if let &InstructionData::Binary {
|
|
opcode: ref pattern5_0,
|
|
args: ref pattern5_1,
|
|
} = &pattern4_0
|
|
{
|
|
match &pattern5_0 {
|
|
&Opcode::Umulhi => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 389.
|
|
let expr0_0 = ALUOp::UMulH;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = constructor_alu_rrr(ctx, &expr0_0, expr1_0, expr2_0)?;
|
|
let expr4_0 = C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
&Opcode::Smulhi => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 375.
|
|
let expr0_0 = ALUOp::SMulH;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = constructor_alu_rrr(ctx, &expr0_0, expr1_0, expr2_0)?;
|
|
let expr4_0 = C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
&Opcode::Band => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 632.
|
|
let expr0_0 = ALUOp::And64;
|
|
let expr1_0: Type = I64;
|
|
let expr2_0 = constructor_alu_rs_imm_logic_commutative(
|
|
ctx, &expr0_0, expr1_0, pattern7_0, pattern7_1,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
&Opcode::Bor => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 645.
|
|
let expr0_0 = ALUOp::Orr64;
|
|
let expr1_0: Type = I64;
|
|
let expr2_0 = constructor_alu_rs_imm_logic_commutative(
|
|
ctx, &expr0_0, expr1_0, pattern7_0, pattern7_1,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
&Opcode::Bxor => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 658.
|
|
let expr0_0 = ALUOp::Eor64;
|
|
let expr1_0: Type = I64;
|
|
let expr2_0 = constructor_alu_rs_imm_logic_commutative(
|
|
ctx, &expr0_0, expr1_0, pattern7_0, pattern7_1,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
&Opcode::BandNot => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 671.
|
|
let expr0_0 = ALUOp::AndNot64;
|
|
let expr1_0: Type = I64;
|
|
let expr2_0 = constructor_alu_rs_imm_logic(
|
|
ctx, &expr0_0, expr1_0, pattern7_0, pattern7_1,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
&Opcode::BorNot => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 684.
|
|
let expr0_0 = ALUOp::OrrNot64;
|
|
let expr1_0: Type = I64;
|
|
let expr2_0 = constructor_alu_rs_imm_logic(
|
|
ctx, &expr0_0, expr1_0, pattern7_0, pattern7_1,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
&Opcode::BxorNot => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 694.
|
|
let expr0_0 = ALUOp::EorNot64;
|
|
let expr1_0: Type = I64;
|
|
let expr2_0 = constructor_alu_rs_imm_logic(
|
|
ctx, &expr0_0, expr1_0, pattern7_0, pattern7_1,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
if pattern2_0 == I128 {
|
|
let pattern4_0 = C::inst_data(ctx, pattern0_0);
|
|
match &pattern4_0 {
|
|
&InstructionData::Binary {
|
|
opcode: ref pattern5_0,
|
|
args: ref pattern5_1,
|
|
} => {
|
|
match &pattern5_0 {
|
|
&Opcode::Iadd => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 94.
|
|
let expr0_0 = C::put_in_regs(ctx, pattern7_0);
|
|
let expr1_0: usize = 0;
|
|
let expr2_0 = C::value_regs_get(ctx, expr0_0, expr1_0);
|
|
let expr3_0: usize = 1;
|
|
let expr4_0 = C::value_regs_get(ctx, expr0_0, expr3_0);
|
|
let expr5_0 = C::put_in_regs(ctx, pattern7_1);
|
|
let expr6_0: usize = 0;
|
|
let expr7_0 = C::value_regs_get(ctx, expr5_0, expr6_0);
|
|
let expr8_0: usize = 1;
|
|
let expr9_0 = C::value_regs_get(ctx, expr5_0, expr8_0);
|
|
let expr10_0 = constructor_add64_with_flags(ctx, expr2_0, expr7_0)?;
|
|
let expr11_0 = constructor_adc64(ctx, expr4_0, expr9_0)?;
|
|
let expr12_0 = constructor_with_flags(ctx, &expr10_0, &expr11_0)?;
|
|
return Some(expr12_0);
|
|
}
|
|
&Opcode::Isub => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 145.
|
|
let expr0_0 = C::put_in_regs(ctx, pattern7_0);
|
|
let expr1_0: usize = 0;
|
|
let expr2_0 = C::value_regs_get(ctx, expr0_0, expr1_0);
|
|
let expr3_0: usize = 1;
|
|
let expr4_0 = C::value_regs_get(ctx, expr0_0, expr3_0);
|
|
let expr5_0 = C::put_in_regs(ctx, pattern7_1);
|
|
let expr6_0: usize = 0;
|
|
let expr7_0 = C::value_regs_get(ctx, expr5_0, expr6_0);
|
|
let expr8_0: usize = 1;
|
|
let expr9_0 = C::value_regs_get(ctx, expr5_0, expr8_0);
|
|
let expr10_0 = constructor_sub64_with_flags(ctx, expr2_0, expr7_0)?;
|
|
let expr11_0 = constructor_sbc64(ctx, expr4_0, expr9_0)?;
|
|
let expr12_0 = constructor_with_flags(ctx, &expr10_0, &expr11_0)?;
|
|
return Some(expr12_0);
|
|
}
|
|
&Opcode::Imul => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 200.
|
|
let expr0_0 = C::put_in_regs(ctx, pattern7_0);
|
|
let expr1_0: usize = 0;
|
|
let expr2_0 = C::value_regs_get(ctx, expr0_0, expr1_0);
|
|
let expr3_0: usize = 1;
|
|
let expr4_0 = C::value_regs_get(ctx, expr0_0, expr3_0);
|
|
let expr5_0 = C::put_in_regs(ctx, pattern7_1);
|
|
let expr6_0: usize = 0;
|
|
let expr7_0 = C::value_regs_get(ctx, expr5_0, expr6_0);
|
|
let expr8_0: usize = 1;
|
|
let expr9_0 = C::value_regs_get(ctx, expr5_0, expr8_0);
|
|
let expr10_0 = ALUOp::UMulH;
|
|
let expr11_0 = constructor_alu_rrr(ctx, &expr10_0, expr2_0, expr7_0)?;
|
|
let expr12_0 = ALUOp3::MAdd64;
|
|
let expr13_0 =
|
|
constructor_alu_rrrr(ctx, &expr12_0, expr2_0, expr9_0, expr11_0)?;
|
|
let expr14_0 = ALUOp3::MAdd64;
|
|
let expr15_0 =
|
|
constructor_alu_rrrr(ctx, &expr14_0, expr4_0, expr7_0, expr13_0)?;
|
|
let expr16_0 = ALUOp3::MAdd64;
|
|
let expr17_0 = C::zero_reg(ctx);
|
|
let expr18_0 =
|
|
constructor_alu_rrrr(ctx, &expr16_0, expr2_0, expr7_0, expr17_0)?;
|
|
let expr19_0 = C::value_regs(ctx, expr18_0, expr15_0);
|
|
return Some(expr19_0);
|
|
}
|
|
&Opcode::Band => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 635.
|
|
let expr0_0 = ALUOp::And64;
|
|
let expr1_0 =
|
|
constructor_i128_alu_bitop(ctx, &expr0_0, pattern7_0, pattern7_1)?;
|
|
return Some(expr1_0);
|
|
}
|
|
&Opcode::Bor => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 648.
|
|
let expr0_0 = ALUOp::Orr64;
|
|
let expr1_0 =
|
|
constructor_i128_alu_bitop(ctx, &expr0_0, pattern7_0, pattern7_1)?;
|
|
return Some(expr1_0);
|
|
}
|
|
&Opcode::Bxor => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 661.
|
|
let expr0_0 = ALUOp::Eor64;
|
|
let expr1_0 =
|
|
constructor_i128_alu_bitop(ctx, &expr0_0, pattern7_0, pattern7_1)?;
|
|
return Some(expr1_0);
|
|
}
|
|
&Opcode::BandNot => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 674.
|
|
let expr0_0 = ALUOp::AndNot64;
|
|
let expr1_0 =
|
|
constructor_i128_alu_bitop(ctx, &expr0_0, pattern7_0, pattern7_1)?;
|
|
return Some(expr1_0);
|
|
}
|
|
&Opcode::BorNot => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 687.
|
|
let expr0_0 = ALUOp::OrrNot64;
|
|
let expr1_0 =
|
|
constructor_i128_alu_bitop(ctx, &expr0_0, pattern7_0, pattern7_1)?;
|
|
return Some(expr1_0);
|
|
}
|
|
&Opcode::BxorNot => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 697.
|
|
let expr0_0 = ALUOp::EorNot64;
|
|
let expr1_0 =
|
|
constructor_i128_alu_bitop(ctx, &expr0_0, pattern7_0, pattern7_1)?;
|
|
return Some(expr1_0);
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
&InstructionData::Unary {
|
|
opcode: ref pattern5_0,
|
|
arg: pattern5_1,
|
|
} => {
|
|
match &pattern5_0 {
|
|
&Opcode::Bnot => {
|
|
// Rule at src/isa/aarch64/lower.isle line 613.
|
|
let expr0_0 = C::put_in_regs(ctx, pattern5_1);
|
|
let expr1_0: usize = 0;
|
|
let expr2_0 = C::value_regs_get(ctx, expr0_0, expr1_0);
|
|
let expr3_0: usize = 1;
|
|
let expr4_0 = C::value_regs_get(ctx, expr0_0, expr3_0);
|
|
let expr5_0 = ALUOp::OrrNot64;
|
|
let expr6_0 = C::zero_reg(ctx);
|
|
let expr7_0 = constructor_alu_rrr(ctx, &expr5_0, expr6_0, expr2_0)?;
|
|
let expr8_0 = ALUOp::OrrNot64;
|
|
let expr9_0 = C::zero_reg(ctx);
|
|
let expr10_0 = constructor_alu_rrr(ctx, &expr8_0, expr9_0, expr4_0)?;
|
|
let expr11_0 = C::value_regs(ctx, expr7_0, expr10_0);
|
|
return Some(expr11_0);
|
|
}
|
|
&Opcode::Uextend => {
|
|
if let Some(pattern7_0) = C::def_inst(ctx, pattern5_1) {
|
|
let pattern8_0 = C::inst_data(ctx, pattern7_0);
|
|
if let &InstructionData::BinaryImm8 {
|
|
opcode: ref pattern9_0,
|
|
arg: pattern9_1,
|
|
imm: pattern9_2,
|
|
} = &pattern8_0
|
|
{
|
|
if let &Opcode::Extractlane = &pattern9_0 {
|
|
let pattern11_0 = C::value_type(ctx, pattern9_1);
|
|
let pattern12_0 = C::u8_from_uimm8(ctx, pattern9_2);
|
|
// Rule at src/isa/aarch64/lower.isle line 533.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern9_1);
|
|
let expr1_0 = constructor_vector_size(ctx, pattern11_0)?;
|
|
let expr2_0 = constructor_mov_from_vec(
|
|
ctx,
|
|
expr0_0,
|
|
pattern12_0,
|
|
&expr1_0,
|
|
)?;
|
|
let expr3_0: Type = I64;
|
|
let expr4_0: u64 = 0;
|
|
let expr5_0 = constructor_imm(ctx, expr3_0, expr4_0)?;
|
|
let expr6_0 = C::value_regs(ctx, expr2_0, expr5_0);
|
|
return Some(expr6_0);
|
|
}
|
|
}
|
|
}
|
|
// Rule at src/isa/aarch64/lower.isle line 528.
|
|
let expr0_0 = constructor_put_in_reg_zext64(ctx, pattern5_1)?;
|
|
let expr1_0: Type = I64;
|
|
let expr2_0: u64 = 0;
|
|
let expr3_0 = constructor_imm(ctx, expr1_0, expr2_0)?;
|
|
let expr4_0 = C::value_regs(ctx, expr0_0, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
&Opcode::Sextend => {
|
|
if let Some(pattern7_0) = C::def_inst(ctx, pattern5_1) {
|
|
let pattern8_0 = C::inst_data(ctx, pattern7_0);
|
|
if let &InstructionData::BinaryImm8 {
|
|
opcode: ref pattern9_0,
|
|
arg: pattern9_1,
|
|
imm: pattern9_2,
|
|
} = &pattern8_0
|
|
{
|
|
if let &Opcode::Extractlane = &pattern9_0 {
|
|
let pattern11_0 = C::value_type(ctx, pattern9_1);
|
|
if pattern11_0 == I64X2 {
|
|
let pattern13_0 = C::u8_from_uimm8(ctx, pattern9_2);
|
|
// Rule at src/isa/aarch64/lower.isle line 581.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern9_1);
|
|
let expr1_0 = VectorSize::Size64x2;
|
|
let expr2_0 = constructor_mov_from_vec(
|
|
ctx,
|
|
expr0_0,
|
|
pattern13_0,
|
|
&expr1_0,
|
|
)?;
|
|
let expr3_0 = ALUOp::Asr64;
|
|
let expr4_0: u8 = 63;
|
|
let expr5_0 = C::imm_shift_from_u8(ctx, expr4_0);
|
|
let expr6_0 = constructor_alu_rr_imm_shift(
|
|
ctx, &expr3_0, expr2_0, expr5_0,
|
|
)?;
|
|
let expr7_0 = C::value_regs(ctx, expr2_0, expr6_0);
|
|
return Some(expr7_0);
|
|
}
|
|
if let Some(()) = C::not_i64x2(ctx, pattern11_0) {
|
|
let pattern13_0 = C::u8_from_uimm8(ctx, pattern9_2);
|
|
// Rule at src/isa/aarch64/lower.isle line 568.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern9_1);
|
|
let expr1_0 =
|
|
constructor_vector_size(ctx, pattern11_0)?;
|
|
let expr2_0: Type = I64;
|
|
let expr3_0 = constructor_size_from_ty(ctx, expr2_0)?;
|
|
let expr4_0 = constructor_mov_from_vec_signed(
|
|
ctx,
|
|
expr0_0,
|
|
pattern13_0,
|
|
&expr1_0,
|
|
&expr3_0,
|
|
)?;
|
|
let expr5_0 = ALUOp::Asr64;
|
|
let expr6_0: u8 = 63;
|
|
let expr7_0 = C::imm_shift_from_u8(ctx, expr6_0);
|
|
let expr8_0 = constructor_alu_rr_imm_shift(
|
|
ctx, &expr5_0, expr4_0, expr7_0,
|
|
)?;
|
|
let expr9_0 = C::value_regs(ctx, expr4_0, expr8_0);
|
|
return Some(expr9_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Rule at src/isa/aarch64/lower.isle line 556.
|
|
let expr0_0 = constructor_put_in_reg_sext64(ctx, pattern5_1)?;
|
|
let expr1_0 = ALUOp::Asr64;
|
|
let expr2_0: u8 = 63;
|
|
let expr3_0 = C::imm_shift_from_u8(ctx, expr2_0);
|
|
let expr4_0 =
|
|
constructor_alu_rr_imm_shift(ctx, &expr1_0, expr0_0, expr3_0)?;
|
|
let expr5_0 = C::value_regs(ctx, expr0_0, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
if pattern2_0 == I16X8 {
|
|
let pattern4_0 = C::inst_data(ctx, pattern0_0);
|
|
if let &InstructionData::Binary {
|
|
opcode: ref pattern5_0,
|
|
args: ref pattern5_1,
|
|
} = &pattern4_0
|
|
{
|
|
if let &Opcode::Imul = &pattern5_0 {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
if let Some(pattern8_0) = C::def_inst(ctx, pattern7_0) {
|
|
let pattern9_0 = C::inst_data(ctx, pattern8_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern10_0,
|
|
arg: pattern10_1,
|
|
} = &pattern9_0
|
|
{
|
|
match &pattern10_0 {
|
|
&Opcode::SwidenLow => {
|
|
let pattern12_0 = C::value_type(ctx, pattern10_1);
|
|
if pattern12_0 == I8X16 {
|
|
if let Some(pattern14_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern15_0 = C::inst_data(ctx, pattern14_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern16_0,
|
|
arg: pattern16_1,
|
|
} = &pattern15_0
|
|
{
|
|
if let &Opcode::SwidenLow = &pattern16_0 {
|
|
let pattern18_0 =
|
|
C::value_type(ctx, pattern16_1);
|
|
if pattern18_0 == I8X16 {
|
|
// Rule at src/isa/aarch64/lower.isle line 302.
|
|
let expr0_0 = VecRRRLongOp::Smull8;
|
|
let expr1_0 =
|
|
C::put_in_reg(ctx, pattern10_1);
|
|
let expr2_0 =
|
|
C::put_in_reg(ctx, pattern16_1);
|
|
let expr3_0: bool = false;
|
|
let expr4_0 = constructor_vec_rrr_long(
|
|
ctx, &expr0_0, expr1_0, expr2_0,
|
|
expr3_0,
|
|
)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
&Opcode::SwidenHigh => {
|
|
let pattern12_0 = C::value_type(ctx, pattern10_1);
|
|
if pattern12_0 == I8X16 {
|
|
if let Some(pattern14_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern15_0 = C::inst_data(ctx, pattern14_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern16_0,
|
|
arg: pattern16_1,
|
|
} = &pattern15_0
|
|
{
|
|
if let &Opcode::SwidenHigh = &pattern16_0 {
|
|
let pattern18_0 =
|
|
C::value_type(ctx, pattern16_1);
|
|
if pattern18_0 == I8X16 {
|
|
// Rule at src/isa/aarch64/lower.isle line 308.
|
|
let expr0_0 = VecRRRLongOp::Smull8;
|
|
let expr1_0 =
|
|
C::put_in_reg(ctx, pattern10_1);
|
|
let expr2_0 =
|
|
C::put_in_reg(ctx, pattern16_1);
|
|
let expr3_0: bool = true;
|
|
let expr4_0 = constructor_vec_rrr_long(
|
|
ctx, &expr0_0, expr1_0, expr2_0,
|
|
expr3_0,
|
|
)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
&Opcode::UwidenLow => {
|
|
let pattern12_0 = C::value_type(ctx, pattern10_1);
|
|
if pattern12_0 == I8X16 {
|
|
if let Some(pattern14_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern15_0 = C::inst_data(ctx, pattern14_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern16_0,
|
|
arg: pattern16_1,
|
|
} = &pattern15_0
|
|
{
|
|
if let &Opcode::UwidenLow = &pattern16_0 {
|
|
let pattern18_0 =
|
|
C::value_type(ctx, pattern16_1);
|
|
if pattern18_0 == I8X16 {
|
|
// Rule at src/isa/aarch64/lower.isle line 314.
|
|
let expr0_0 = VecRRRLongOp::Umull8;
|
|
let expr1_0 =
|
|
C::put_in_reg(ctx, pattern10_1);
|
|
let expr2_0 =
|
|
C::put_in_reg(ctx, pattern16_1);
|
|
let expr3_0: bool = false;
|
|
let expr4_0 = constructor_vec_rrr_long(
|
|
ctx, &expr0_0, expr1_0, expr2_0,
|
|
expr3_0,
|
|
)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
&Opcode::UwidenHigh => {
|
|
let pattern12_0 = C::value_type(ctx, pattern10_1);
|
|
if pattern12_0 == I8X16 {
|
|
if let Some(pattern14_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern15_0 = C::inst_data(ctx, pattern14_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern16_0,
|
|
arg: pattern16_1,
|
|
} = &pattern15_0
|
|
{
|
|
if let &Opcode::UwidenHigh = &pattern16_0 {
|
|
let pattern18_0 =
|
|
C::value_type(ctx, pattern16_1);
|
|
if pattern18_0 == I8X16 {
|
|
// Rule at src/isa/aarch64/lower.isle line 320.
|
|
let expr0_0 = VecRRRLongOp::Umull8;
|
|
let expr1_0 =
|
|
C::put_in_reg(ctx, pattern10_1);
|
|
let expr2_0 =
|
|
C::put_in_reg(ctx, pattern16_1);
|
|
let expr3_0: bool = true;
|
|
let expr4_0 = constructor_vec_rrr_long(
|
|
ctx, &expr0_0, expr1_0, expr2_0,
|
|
expr3_0,
|
|
)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if pattern2_0 == I32X4 {
|
|
let pattern4_0 = C::inst_data(ctx, pattern0_0);
|
|
if let &InstructionData::Binary {
|
|
opcode: ref pattern5_0,
|
|
args: ref pattern5_1,
|
|
} = &pattern4_0
|
|
{
|
|
if let &Opcode::Imul = &pattern5_0 {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
if let Some(pattern8_0) = C::def_inst(ctx, pattern7_0) {
|
|
let pattern9_0 = C::inst_data(ctx, pattern8_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern10_0,
|
|
arg: pattern10_1,
|
|
} = &pattern9_0
|
|
{
|
|
match &pattern10_0 {
|
|
&Opcode::SwidenLow => {
|
|
let pattern12_0 = C::value_type(ctx, pattern10_1);
|
|
if pattern12_0 == I16X8 {
|
|
if let Some(pattern14_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern15_0 = C::inst_data(ctx, pattern14_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern16_0,
|
|
arg: pattern16_1,
|
|
} = &pattern15_0
|
|
{
|
|
if let &Opcode::SwidenLow = &pattern16_0 {
|
|
let pattern18_0 =
|
|
C::value_type(ctx, pattern16_1);
|
|
if pattern18_0 == I16X8 {
|
|
// Rule at src/isa/aarch64/lower.isle line 326.
|
|
let expr0_0 = VecRRRLongOp::Smull16;
|
|
let expr1_0 =
|
|
C::put_in_reg(ctx, pattern10_1);
|
|
let expr2_0 =
|
|
C::put_in_reg(ctx, pattern16_1);
|
|
let expr3_0: bool = false;
|
|
let expr4_0 = constructor_vec_rrr_long(
|
|
ctx, &expr0_0, expr1_0, expr2_0,
|
|
expr3_0,
|
|
)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
&Opcode::SwidenHigh => {
|
|
let pattern12_0 = C::value_type(ctx, pattern10_1);
|
|
if pattern12_0 == I16X8 {
|
|
if let Some(pattern14_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern15_0 = C::inst_data(ctx, pattern14_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern16_0,
|
|
arg: pattern16_1,
|
|
} = &pattern15_0
|
|
{
|
|
if let &Opcode::SwidenHigh = &pattern16_0 {
|
|
let pattern18_0 =
|
|
C::value_type(ctx, pattern16_1);
|
|
if pattern18_0 == I16X8 {
|
|
// Rule at src/isa/aarch64/lower.isle line 332.
|
|
let expr0_0 = VecRRRLongOp::Smull16;
|
|
let expr1_0 =
|
|
C::put_in_reg(ctx, pattern10_1);
|
|
let expr2_0 =
|
|
C::put_in_reg(ctx, pattern16_1);
|
|
let expr3_0: bool = true;
|
|
let expr4_0 = constructor_vec_rrr_long(
|
|
ctx, &expr0_0, expr1_0, expr2_0,
|
|
expr3_0,
|
|
)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
&Opcode::UwidenLow => {
|
|
let pattern12_0 = C::value_type(ctx, pattern10_1);
|
|
if pattern12_0 == I16X8 {
|
|
if let Some(pattern14_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern15_0 = C::inst_data(ctx, pattern14_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern16_0,
|
|
arg: pattern16_1,
|
|
} = &pattern15_0
|
|
{
|
|
if let &Opcode::UwidenLow = &pattern16_0 {
|
|
let pattern18_0 =
|
|
C::value_type(ctx, pattern16_1);
|
|
if pattern18_0 == I16X8 {
|
|
// Rule at src/isa/aarch64/lower.isle line 338.
|
|
let expr0_0 = VecRRRLongOp::Umull16;
|
|
let expr1_0 =
|
|
C::put_in_reg(ctx, pattern10_1);
|
|
let expr2_0 =
|
|
C::put_in_reg(ctx, pattern16_1);
|
|
let expr3_0: bool = false;
|
|
let expr4_0 = constructor_vec_rrr_long(
|
|
ctx, &expr0_0, expr1_0, expr2_0,
|
|
expr3_0,
|
|
)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
&Opcode::UwidenHigh => {
|
|
let pattern12_0 = C::value_type(ctx, pattern10_1);
|
|
if pattern12_0 == I16X8 {
|
|
if let Some(pattern14_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern15_0 = C::inst_data(ctx, pattern14_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern16_0,
|
|
arg: pattern16_1,
|
|
} = &pattern15_0
|
|
{
|
|
if let &Opcode::UwidenHigh = &pattern16_0 {
|
|
let pattern18_0 =
|
|
C::value_type(ctx, pattern16_1);
|
|
if pattern18_0 == I16X8 {
|
|
// Rule at src/isa/aarch64/lower.isle line 344.
|
|
let expr0_0 = VecRRRLongOp::Umull16;
|
|
let expr1_0 =
|
|
C::put_in_reg(ctx, pattern10_1);
|
|
let expr2_0 =
|
|
C::put_in_reg(ctx, pattern16_1);
|
|
let expr3_0: bool = true;
|
|
let expr4_0 = constructor_vec_rrr_long(
|
|
ctx, &expr0_0, expr1_0, expr2_0,
|
|
expr3_0,
|
|
)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if pattern2_0 == I64X2 {
|
|
let pattern4_0 = C::inst_data(ctx, pattern0_0);
|
|
if let &InstructionData::Binary {
|
|
opcode: ref pattern5_0,
|
|
args: ref pattern5_1,
|
|
} = &pattern4_0
|
|
{
|
|
if let &Opcode::Imul = &pattern5_0 {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
if let Some(pattern8_0) = C::def_inst(ctx, pattern7_0) {
|
|
let pattern9_0 = C::inst_data(ctx, pattern8_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern10_0,
|
|
arg: pattern10_1,
|
|
} = &pattern9_0
|
|
{
|
|
match &pattern10_0 {
|
|
&Opcode::SwidenLow => {
|
|
let pattern12_0 = C::value_type(ctx, pattern10_1);
|
|
if pattern12_0 == I32X4 {
|
|
if let Some(pattern14_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern15_0 = C::inst_data(ctx, pattern14_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern16_0,
|
|
arg: pattern16_1,
|
|
} = &pattern15_0
|
|
{
|
|
if let &Opcode::SwidenLow = &pattern16_0 {
|
|
let pattern18_0 =
|
|
C::value_type(ctx, pattern16_1);
|
|
if pattern18_0 == I32X4 {
|
|
// Rule at src/isa/aarch64/lower.isle line 350.
|
|
let expr0_0 = VecRRRLongOp::Smull32;
|
|
let expr1_0 =
|
|
C::put_in_reg(ctx, pattern10_1);
|
|
let expr2_0 =
|
|
C::put_in_reg(ctx, pattern16_1);
|
|
let expr3_0: bool = false;
|
|
let expr4_0 = constructor_vec_rrr_long(
|
|
ctx, &expr0_0, expr1_0, expr2_0,
|
|
expr3_0,
|
|
)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
&Opcode::SwidenHigh => {
|
|
let pattern12_0 = C::value_type(ctx, pattern10_1);
|
|
if pattern12_0 == I32X4 {
|
|
if let Some(pattern14_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern15_0 = C::inst_data(ctx, pattern14_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern16_0,
|
|
arg: pattern16_1,
|
|
} = &pattern15_0
|
|
{
|
|
if let &Opcode::SwidenHigh = &pattern16_0 {
|
|
let pattern18_0 =
|
|
C::value_type(ctx, pattern16_1);
|
|
if pattern18_0 == I32X4 {
|
|
// Rule at src/isa/aarch64/lower.isle line 356.
|
|
let expr0_0 = VecRRRLongOp::Smull32;
|
|
let expr1_0 =
|
|
C::put_in_reg(ctx, pattern10_1);
|
|
let expr2_0 =
|
|
C::put_in_reg(ctx, pattern16_1);
|
|
let expr3_0: bool = true;
|
|
let expr4_0 = constructor_vec_rrr_long(
|
|
ctx, &expr0_0, expr1_0, expr2_0,
|
|
expr3_0,
|
|
)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
&Opcode::UwidenLow => {
|
|
let pattern12_0 = C::value_type(ctx, pattern10_1);
|
|
if pattern12_0 == I32X4 {
|
|
if let Some(pattern14_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern15_0 = C::inst_data(ctx, pattern14_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern16_0,
|
|
arg: pattern16_1,
|
|
} = &pattern15_0
|
|
{
|
|
if let &Opcode::UwidenLow = &pattern16_0 {
|
|
let pattern18_0 =
|
|
C::value_type(ctx, pattern16_1);
|
|
if pattern18_0 == I32X4 {
|
|
// Rule at src/isa/aarch64/lower.isle line 362.
|
|
let expr0_0 = VecRRRLongOp::Umull32;
|
|
let expr1_0 =
|
|
C::put_in_reg(ctx, pattern10_1);
|
|
let expr2_0 =
|
|
C::put_in_reg(ctx, pattern16_1);
|
|
let expr3_0: bool = false;
|
|
let expr4_0 = constructor_vec_rrr_long(
|
|
ctx, &expr0_0, expr1_0, expr2_0,
|
|
expr3_0,
|
|
)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
&Opcode::UwidenHigh => {
|
|
let pattern12_0 = C::value_type(ctx, pattern10_1);
|
|
if pattern12_0 == I32X4 {
|
|
if let Some(pattern14_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern15_0 = C::inst_data(ctx, pattern14_0);
|
|
if let &InstructionData::Unary {
|
|
opcode: ref pattern16_0,
|
|
arg: pattern16_1,
|
|
} = &pattern15_0
|
|
{
|
|
if let &Opcode::UwidenHigh = &pattern16_0 {
|
|
let pattern18_0 =
|
|
C::value_type(ctx, pattern16_1);
|
|
if pattern18_0 == I32X4 {
|
|
// Rule at src/isa/aarch64/lower.isle line 368.
|
|
let expr0_0 = VecRRRLongOp::Umull32;
|
|
let expr1_0 =
|
|
C::put_in_reg(ctx, pattern10_1);
|
|
let expr2_0 =
|
|
C::put_in_reg(ctx, pattern16_1);
|
|
let expr3_0: bool = true;
|
|
let expr4_0 = constructor_vec_rrr_long(
|
|
ctx, &expr0_0, expr1_0, expr2_0,
|
|
expr3_0,
|
|
)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
// Rule at src/isa/aarch64/lower.isle line 261.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr2_0 = VecMisc2::Rev64;
|
|
let expr3_0 = VectorSize::Size32x4;
|
|
let expr4_0 = constructor_vec_misc(ctx, &expr2_0, expr1_0, &expr3_0)?;
|
|
let expr5_0 = VecALUOp::Mul;
|
|
let expr6_0 = VectorSize::Size32x4;
|
|
let expr7_0 = constructor_vec_rrr(ctx, &expr5_0, expr4_0, expr0_0, &expr6_0)?;
|
|
let expr8_0 = VecRRNarrowOp::Xtn64;
|
|
let expr9_0: bool = false;
|
|
let expr10_0 = constructor_vec_rr_narrow(ctx, &expr8_0, expr0_0, expr9_0)?;
|
|
let expr11_0 = VecALUOp::Addp;
|
|
let expr12_0 = VectorSize::Size32x4;
|
|
let expr13_0 =
|
|
constructor_vec_rrr(ctx, &expr11_0, expr7_0, expr7_0, &expr12_0)?;
|
|
let expr14_0 = VecRRNarrowOp::Xtn64;
|
|
let expr15_0: bool = false;
|
|
let expr16_0 = constructor_vec_rr_narrow(ctx, &expr14_0, expr1_0, expr15_0)?;
|
|
let expr17_0 = VecRRLongOp::Shll32;
|
|
let expr18_0: bool = false;
|
|
let expr19_0 = constructor_vec_rr_long(ctx, &expr17_0, expr13_0, expr18_0)?;
|
|
let expr20_0 = VecRRRLongOp::Umlal32;
|
|
let expr21_0: bool = false;
|
|
let expr22_0 = constructor_vec_rrrr_long(
|
|
ctx, &expr20_0, expr19_0, expr16_0, expr10_0, expr21_0,
|
|
)?;
|
|
let expr23_0 = C::value_reg(ctx, expr22_0);
|
|
return Some(expr23_0);
|
|
}
|
|
}
|
|
}
|
|
let pattern3_0 = C::inst_data(ctx, pattern0_0);
|
|
match &pattern3_0 {
|
|
&InstructionData::NullAry {
|
|
opcode: ref pattern4_0,
|
|
} => {
|
|
if let &Opcode::Null = &pattern4_0 {
|
|
// Rule at src/isa/aarch64/lower.isle line 22.
|
|
let expr0_0: u64 = 0;
|
|
let expr1_0 = constructor_imm(ctx, pattern2_0, expr0_0)?;
|
|
let expr2_0 = C::value_reg(ctx, expr1_0);
|
|
return Some(expr2_0);
|
|
}
|
|
}
|
|
&InstructionData::UnaryImm {
|
|
opcode: ref pattern4_0,
|
|
imm: pattern4_1,
|
|
} => {
|
|
if let &Opcode::Iconst = &pattern4_0 {
|
|
let pattern6_0 = C::u64_from_imm64(ctx, pattern4_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 9.
|
|
let expr0_0 = constructor_imm(ctx, pattern2_0, pattern6_0)?;
|
|
let expr1_0 = C::value_reg(ctx, expr0_0);
|
|
return Some(expr1_0);
|
|
}
|
|
}
|
|
&InstructionData::UnaryBool {
|
|
opcode: ref pattern4_0,
|
|
imm: pattern4_1,
|
|
} => {
|
|
if let &Opcode::Bconst = &pattern4_0 {
|
|
if pattern4_1 == true {
|
|
// Rule at src/isa/aarch64/lower.isle line 17.
|
|
let expr0_0: u64 = 1;
|
|
let expr1_0 = constructor_imm(ctx, pattern2_0, expr0_0)?;
|
|
let expr2_0 = C::value_reg(ctx, expr1_0);
|
|
return Some(expr2_0);
|
|
}
|
|
if pattern4_1 == false {
|
|
// Rule at src/isa/aarch64/lower.isle line 14.
|
|
let expr0_0: u64 = 0;
|
|
let expr1_0 = constructor_imm(ctx, pattern2_0, expr0_0)?;
|
|
let expr2_0 = C::value_reg(ctx, expr1_0);
|
|
return Some(expr2_0);
|
|
}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
if let Some((pattern3_0, pattern3_1)) = C::multi_lane(ctx, pattern2_0) {
|
|
let pattern4_0 = C::inst_data(ctx, pattern0_0);
|
|
if let &InstructionData::Binary {
|
|
opcode: ref pattern5_0,
|
|
args: ref pattern5_1,
|
|
} = &pattern4_0
|
|
{
|
|
match &pattern5_0 {
|
|
&Opcode::Iadd => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 90.
|
|
let expr0_0 = VecALUOp::Add;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = constructor_vector_size(ctx, pattern2_0)?;
|
|
let expr4_0 =
|
|
constructor_vec_rrr(ctx, &expr0_0, expr1_0, expr2_0, &expr3_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
&Opcode::Isub => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 141.
|
|
let expr0_0 = VecALUOp::Sub;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = constructor_vector_size(ctx, pattern2_0)?;
|
|
let expr4_0 =
|
|
constructor_vec_rrr(ctx, &expr0_0, expr1_0, expr2_0, &expr3_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
if let Some(pattern3_0) = C::fits_in_32(ctx, pattern2_0) {
|
|
let pattern4_0 = C::inst_data(ctx, pattern0_0);
|
|
if let &InstructionData::Binary {
|
|
opcode: ref pattern5_0,
|
|
args: ref pattern5_1,
|
|
} = &pattern4_0
|
|
{
|
|
match &pattern5_0 {
|
|
&Opcode::Umulhi => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 392.
|
|
let expr0_0 = constructor_put_in_reg_zext64(ctx, pattern7_0)?;
|
|
let expr1_0 = constructor_put_in_reg_zext64(ctx, pattern7_1)?;
|
|
let expr2_0 = ALUOp3::MAdd64;
|
|
let expr3_0 = C::zero_reg(ctx);
|
|
let expr4_0 =
|
|
constructor_alu_rrrr(ctx, &expr2_0, expr0_0, expr1_0, expr3_0)?;
|
|
let expr5_0 = ALUOp::Lsr64;
|
|
let expr6_0 = C::ty_bits(ctx, pattern3_0);
|
|
let expr7_0 = C::imm_shift_from_u8(ctx, expr6_0);
|
|
let expr8_0 =
|
|
constructor_alu_rr_imm_shift(ctx, &expr5_0, expr4_0, expr7_0)?;
|
|
let expr9_0 = C::value_reg(ctx, expr8_0);
|
|
return Some(expr9_0);
|
|
}
|
|
&Opcode::Smulhi => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 378.
|
|
let expr0_0 = constructor_put_in_reg_sext64(ctx, pattern7_0)?;
|
|
let expr1_0 = constructor_put_in_reg_sext64(ctx, pattern7_1)?;
|
|
let expr2_0 = ALUOp3::MAdd64;
|
|
let expr3_0 = C::zero_reg(ctx);
|
|
let expr4_0 =
|
|
constructor_alu_rrrr(ctx, &expr2_0, expr0_0, expr1_0, expr3_0)?;
|
|
let expr5_0 = ALUOp::Asr64;
|
|
let expr6_0 = C::ty_bits(ctx, pattern3_0);
|
|
let expr7_0 = C::imm_shift_from_u8(ctx, expr6_0);
|
|
let expr8_0 =
|
|
constructor_alu_rr_imm_shift(ctx, &expr5_0, expr4_0, expr7_0)?;
|
|
let expr9_0 = C::value_reg(ctx, expr8_0);
|
|
return Some(expr9_0);
|
|
}
|
|
&Opcode::Band => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 629.
|
|
let expr0_0 = ALUOp::And32;
|
|
let expr1_0 = constructor_alu_rs_imm_logic_commutative(
|
|
ctx, &expr0_0, pattern3_0, pattern7_0, pattern7_1,
|
|
)?;
|
|
let expr2_0 = C::value_reg(ctx, expr1_0);
|
|
return Some(expr2_0);
|
|
}
|
|
&Opcode::Bor => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 642.
|
|
let expr0_0 = ALUOp::Orr32;
|
|
let expr1_0 = constructor_alu_rs_imm_logic_commutative(
|
|
ctx, &expr0_0, pattern3_0, pattern7_0, pattern7_1,
|
|
)?;
|
|
let expr2_0 = C::value_reg(ctx, expr1_0);
|
|
return Some(expr2_0);
|
|
}
|
|
&Opcode::Bxor => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 655.
|
|
let expr0_0 = ALUOp::Eor32;
|
|
let expr1_0 = constructor_alu_rs_imm_logic_commutative(
|
|
ctx, &expr0_0, pattern3_0, pattern7_0, pattern7_1,
|
|
)?;
|
|
let expr2_0 = C::value_reg(ctx, expr1_0);
|
|
return Some(expr2_0);
|
|
}
|
|
&Opcode::BandNot => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 668.
|
|
let expr0_0 = ALUOp::AndNot32;
|
|
let expr1_0 = constructor_alu_rs_imm_logic(
|
|
ctx, &expr0_0, pattern3_0, pattern7_0, pattern7_1,
|
|
)?;
|
|
let expr2_0 = C::value_reg(ctx, expr1_0);
|
|
return Some(expr2_0);
|
|
}
|
|
&Opcode::BorNot => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 681.
|
|
let expr0_0 = ALUOp::OrrNot32;
|
|
let expr1_0 = constructor_alu_rs_imm_logic(
|
|
ctx, &expr0_0, pattern3_0, pattern7_0, pattern7_1,
|
|
)?;
|
|
let expr2_0 = C::value_reg(ctx, expr1_0);
|
|
return Some(expr2_0);
|
|
}
|
|
&Opcode::BxorNot => {
|
|
let (pattern7_0, pattern7_1) = C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 691.
|
|
let expr0_0 = ALUOp::EorNot32;
|
|
let expr1_0 = constructor_alu_rs_imm_logic(
|
|
ctx, &expr0_0, pattern3_0, pattern7_0, pattern7_1,
|
|
)?;
|
|
let expr2_0 = C::value_reg(ctx, expr1_0);
|
|
return Some(expr2_0);
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
if let Some(pattern3_0) = C::fits_in_64(ctx, pattern2_0) {
|
|
let pattern4_0 = C::inst_data(ctx, pattern0_0);
|
|
match &pattern4_0 {
|
|
&InstructionData::Binary {
|
|
opcode: ref pattern5_0,
|
|
args: ref pattern5_1,
|
|
} => {
|
|
match &pattern5_0 {
|
|
&Opcode::Iadd => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
if let Some(pattern8_0) = C::def_inst(ctx, pattern7_0) {
|
|
let pattern9_0 = C::inst_data(ctx, pattern8_0);
|
|
match &pattern9_0 {
|
|
&InstructionData::UnaryImm {
|
|
opcode: ref pattern10_0,
|
|
imm: pattern10_1,
|
|
} => {
|
|
if let &Opcode::Iconst = &pattern10_0 {
|
|
let pattern12_0 = C::u64_from_imm64(ctx, pattern10_1);
|
|
if let Some(pattern13_0) =
|
|
C::imm12_from_u64(ctx, pattern12_0)
|
|
{
|
|
// Rule at src/isa/aarch64/lower.isle line 37.
|
|
let expr0_0 = constructor_iadd_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr2_0 = constructor_alu_rr_imm12(
|
|
ctx,
|
|
&expr0_0,
|
|
expr1_0,
|
|
pattern13_0,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
if let Some(pattern13_0) =
|
|
C::imm12_from_negated_u64(ctx, pattern12_0)
|
|
{
|
|
// Rule at src/isa/aarch64/lower.isle line 45.
|
|
let expr0_0 = constructor_isub_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr2_0 = constructor_alu_rr_imm12(
|
|
ctx,
|
|
&expr0_0,
|
|
expr1_0,
|
|
pattern13_0,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
}
|
|
}
|
|
&InstructionData::Binary {
|
|
opcode: ref pattern10_0,
|
|
args: ref pattern10_1,
|
|
} => {
|
|
match &pattern10_0 {
|
|
&Opcode::Imul => {
|
|
let (pattern12_0, pattern12_1) =
|
|
C::unpack_value_array_2(ctx, &pattern10_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 70.
|
|
let expr0_0 = constructor_madd_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern12_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern12_1);
|
|
let expr3_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr4_0 = constructor_alu_rrrr(
|
|
ctx, &expr0_0, expr1_0, expr2_0, expr3_0,
|
|
)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
&Opcode::Ishl => {
|
|
let (pattern12_0, pattern12_1) =
|
|
C::unpack_value_array_2(ctx, &pattern10_1);
|
|
if let Some(pattern13_0) =
|
|
C::def_inst(ctx, pattern12_1)
|
|
{
|
|
let pattern14_0 =
|
|
C::inst_data(ctx, pattern13_0);
|
|
if let &InstructionData::UnaryImm {
|
|
opcode: ref pattern15_0,
|
|
imm: pattern15_1,
|
|
} = &pattern14_0
|
|
{
|
|
if let &Opcode::Iconst = &pattern15_0 {
|
|
let closure17 = || {
|
|
return Some(pattern3_0);
|
|
};
|
|
if let Some(pattern17_0) = closure17() {
|
|
if let Some(pattern18_0) =
|
|
C::lshl_from_imm64(
|
|
ctx,
|
|
pattern15_1,
|
|
pattern17_0,
|
|
)
|
|
{
|
|
// Rule at src/isa/aarch64/lower.isle line 62.
|
|
let expr0_0 =
|
|
constructor_iadd_op(
|
|
ctx, pattern3_0,
|
|
)?;
|
|
let expr1_0 = C::put_in_reg(
|
|
ctx, pattern7_1,
|
|
);
|
|
let expr2_0 = C::put_in_reg(
|
|
ctx,
|
|
pattern12_0,
|
|
);
|
|
let expr3_0 =
|
|
constructor_alu_rrr_shift(
|
|
ctx,
|
|
&expr0_0,
|
|
expr1_0,
|
|
expr2_0,
|
|
pattern18_0,
|
|
)?;
|
|
let expr4_0 =
|
|
C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
if let Some(pattern8_0) = C::extended_value_from_value(ctx, pattern7_0)
|
|
{
|
|
// Rule at src/isa/aarch64/lower.isle line 53.
|
|
let expr0_0 = constructor_iadd_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr2_0 = constructor_alu_rr_extend_reg(
|
|
ctx,
|
|
&expr0_0,
|
|
expr1_0,
|
|
&pattern8_0,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
if let Some(pattern8_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern9_0 = C::inst_data(ctx, pattern8_0);
|
|
match &pattern9_0 {
|
|
&InstructionData::UnaryImm {
|
|
opcode: ref pattern10_0,
|
|
imm: pattern10_1,
|
|
} => {
|
|
if let &Opcode::Iconst = &pattern10_0 {
|
|
let pattern12_0 = C::u64_from_imm64(ctx, pattern10_1);
|
|
if let Some(pattern13_0) =
|
|
C::imm12_from_u64(ctx, pattern12_0)
|
|
{
|
|
// Rule at src/isa/aarch64/lower.isle line 34.
|
|
let expr0_0 = constructor_iadd_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = constructor_alu_rr_imm12(
|
|
ctx,
|
|
&expr0_0,
|
|
expr1_0,
|
|
pattern13_0,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
if let Some(pattern13_0) =
|
|
C::imm12_from_negated_u64(ctx, pattern12_0)
|
|
{
|
|
// Rule at src/isa/aarch64/lower.isle line 42.
|
|
let expr0_0 = constructor_isub_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = constructor_alu_rr_imm12(
|
|
ctx,
|
|
&expr0_0,
|
|
expr1_0,
|
|
pattern13_0,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
}
|
|
}
|
|
&InstructionData::Binary {
|
|
opcode: ref pattern10_0,
|
|
args: ref pattern10_1,
|
|
} => {
|
|
match &pattern10_0 {
|
|
&Opcode::Imul => {
|
|
let (pattern12_0, pattern12_1) =
|
|
C::unpack_value_array_2(ctx, &pattern10_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 67.
|
|
let expr0_0 = constructor_madd_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern12_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern12_1);
|
|
let expr3_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr4_0 = constructor_alu_rrrr(
|
|
ctx, &expr0_0, expr1_0, expr2_0, expr3_0,
|
|
)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
&Opcode::Ishl => {
|
|
let (pattern12_0, pattern12_1) =
|
|
C::unpack_value_array_2(ctx, &pattern10_1);
|
|
if let Some(pattern13_0) =
|
|
C::def_inst(ctx, pattern12_1)
|
|
{
|
|
let pattern14_0 =
|
|
C::inst_data(ctx, pattern13_0);
|
|
if let &InstructionData::UnaryImm {
|
|
opcode: ref pattern15_0,
|
|
imm: pattern15_1,
|
|
} = &pattern14_0
|
|
{
|
|
if let &Opcode::Iconst = &pattern15_0 {
|
|
let closure17 = || {
|
|
return Some(pattern3_0);
|
|
};
|
|
if let Some(pattern17_0) = closure17() {
|
|
if let Some(pattern18_0) =
|
|
C::lshl_from_imm64(
|
|
ctx,
|
|
pattern15_1,
|
|
pattern17_0,
|
|
)
|
|
{
|
|
// Rule at src/isa/aarch64/lower.isle line 58.
|
|
let expr0_0 =
|
|
constructor_iadd_op(
|
|
ctx, pattern3_0,
|
|
)?;
|
|
let expr1_0 = C::put_in_reg(
|
|
ctx, pattern7_0,
|
|
);
|
|
let expr2_0 = C::put_in_reg(
|
|
ctx,
|
|
pattern12_0,
|
|
);
|
|
let expr3_0 =
|
|
constructor_alu_rrr_shift(
|
|
ctx,
|
|
&expr0_0,
|
|
expr1_0,
|
|
expr2_0,
|
|
pattern18_0,
|
|
)?;
|
|
let expr4_0 =
|
|
C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
if let Some(pattern8_0) = C::extended_value_from_value(ctx, pattern7_1)
|
|
{
|
|
// Rule at src/isa/aarch64/lower.isle line 50.
|
|
let expr0_0 = constructor_iadd_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = constructor_alu_rr_extend_reg(
|
|
ctx,
|
|
&expr0_0,
|
|
expr1_0,
|
|
&pattern8_0,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
// Rule at src/isa/aarch64/lower.isle line 30.
|
|
let expr0_0 = constructor_iadd_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = constructor_alu_rrr(ctx, &expr0_0, expr1_0, expr2_0)?;
|
|
let expr4_0 = C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
&Opcode::Isub => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
if let Some(pattern8_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern9_0 = C::inst_data(ctx, pattern8_0);
|
|
match &pattern9_0 {
|
|
&InstructionData::UnaryImm {
|
|
opcode: ref pattern10_0,
|
|
imm: pattern10_1,
|
|
} => {
|
|
if let &Opcode::Iconst = &pattern10_0 {
|
|
let pattern12_0 = C::u64_from_imm64(ctx, pattern10_1);
|
|
if let Some(pattern13_0) =
|
|
C::imm12_from_u64(ctx, pattern12_0)
|
|
{
|
|
// Rule at src/isa/aarch64/lower.isle line 121.
|
|
let expr0_0 = constructor_isub_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = constructor_alu_rr_imm12(
|
|
ctx,
|
|
&expr0_0,
|
|
expr1_0,
|
|
pattern13_0,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
if let Some(pattern13_0) =
|
|
C::imm12_from_negated_u64(ctx, pattern12_0)
|
|
{
|
|
// Rule at src/isa/aarch64/lower.isle line 126.
|
|
let expr0_0 = constructor_iadd_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = constructor_alu_rr_imm12(
|
|
ctx,
|
|
&expr0_0,
|
|
expr1_0,
|
|
pattern13_0,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
}
|
|
}
|
|
&InstructionData::Binary {
|
|
opcode: ref pattern10_0,
|
|
args: ref pattern10_1,
|
|
} => {
|
|
if let &Opcode::Ishl = &pattern10_0 {
|
|
let (pattern12_0, pattern12_1) =
|
|
C::unpack_value_array_2(ctx, &pattern10_1);
|
|
if let Some(pattern13_0) = C::def_inst(ctx, pattern12_1)
|
|
{
|
|
let pattern14_0 = C::inst_data(ctx, pattern13_0);
|
|
if let &InstructionData::UnaryImm {
|
|
opcode: ref pattern15_0,
|
|
imm: pattern15_1,
|
|
} = &pattern14_0
|
|
{
|
|
if let &Opcode::Iconst = &pattern15_0 {
|
|
let closure17 = || {
|
|
return Some(pattern3_0);
|
|
};
|
|
if let Some(pattern17_0) = closure17() {
|
|
if let Some(pattern18_0) =
|
|
C::lshl_from_imm64(
|
|
ctx,
|
|
pattern15_1,
|
|
pattern17_0,
|
|
)
|
|
{
|
|
// Rule at src/isa/aarch64/lower.isle line 136.
|
|
let expr0_0 = constructor_isub_op(
|
|
ctx, pattern3_0,
|
|
)?;
|
|
let expr1_0 =
|
|
C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 =
|
|
C::put_in_reg(ctx, pattern12_0);
|
|
let expr3_0 =
|
|
constructor_alu_rrr_shift(
|
|
ctx,
|
|
&expr0_0,
|
|
expr1_0,
|
|
expr2_0,
|
|
pattern18_0,
|
|
)?;
|
|
let expr4_0 =
|
|
C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
if let Some(pattern8_0) = C::extended_value_from_value(ctx, pattern7_1)
|
|
{
|
|
// Rule at src/isa/aarch64/lower.isle line 131.
|
|
let expr0_0 = constructor_isub_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = constructor_alu_rr_extend_reg(
|
|
ctx,
|
|
&expr0_0,
|
|
expr1_0,
|
|
&pattern8_0,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
// Rule at src/isa/aarch64/lower.isle line 117.
|
|
let expr0_0 = constructor_isub_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = constructor_alu_rrr(ctx, &expr0_0, expr1_0, expr2_0)?;
|
|
let expr4_0 = C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
&Opcode::Imul => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 196.
|
|
let expr0_0 = constructor_madd_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = C::zero_reg(ctx);
|
|
let expr4_0 =
|
|
constructor_alu_rrrr(ctx, &expr0_0, expr1_0, expr2_0, expr3_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
&Opcode::Udiv => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 408.
|
|
let expr0_0 = ALUOp::UDiv64;
|
|
let expr1_0 = constructor_put_in_reg_zext64(ctx, pattern7_0)?;
|
|
let expr2_0 = constructor_put_nonzero_in_reg_zext64(ctx, pattern7_1)?;
|
|
let expr3_0 = constructor_alu_rrr(ctx, &expr0_0, expr1_0, expr2_0)?;
|
|
let expr4_0 = C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
&Opcode::Sdiv => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
if let Some(pattern8_0) = C::def_inst(ctx, pattern7_1) {
|
|
let pattern9_0 = C::inst_data(ctx, pattern8_0);
|
|
if let &InstructionData::UnaryImm {
|
|
opcode: ref pattern10_0,
|
|
imm: pattern10_1,
|
|
} = &pattern9_0
|
|
{
|
|
if let &Opcode::Iconst = &pattern10_0 {
|
|
if let Some(pattern12_0) =
|
|
C::safe_divisor_from_imm64(ctx, pattern10_1)
|
|
{
|
|
// Rule at src/isa/aarch64/lower.isle line 458.
|
|
let expr0_0 = ALUOp::SDiv64;
|
|
let expr1_0 =
|
|
constructor_put_in_reg_sext64(ctx, pattern7_0)?;
|
|
let expr2_0 =
|
|
constructor_imm(ctx, pattern3_0, pattern12_0)?;
|
|
let expr3_0 = constructor_alu_rrr(
|
|
ctx, &expr0_0, expr1_0, expr2_0,
|
|
)?;
|
|
let expr4_0 = C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Rule at src/isa/aarch64/lower.isle line 443.
|
|
let expr0_0 = constructor_put_in_reg_sext64(ctx, pattern7_0)?;
|
|
let expr1_0 = constructor_put_nonzero_in_reg_sext64(ctx, pattern7_1)?;
|
|
let expr2_0 = constructor_trap_if_div_overflow(
|
|
ctx, pattern3_0, expr0_0, expr1_0,
|
|
)?;
|
|
let expr3_0 = ALUOp::SDiv64;
|
|
let expr4_0 = constructor_alu_rrr(ctx, &expr3_0, expr2_0, expr1_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
&Opcode::Urem => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 488.
|
|
let expr0_0 = constructor_put_in_reg_zext64(ctx, pattern7_0)?;
|
|
let expr1_0 = constructor_put_nonzero_in_reg_zext64(ctx, pattern7_1)?;
|
|
let expr2_0 = ALUOp::UDiv64;
|
|
let expr3_0 = constructor_alu_rrr(ctx, &expr2_0, expr0_0, expr1_0)?;
|
|
let expr4_0 = ALUOp3::MSub64;
|
|
let expr5_0 =
|
|
constructor_alu_rrrr(ctx, &expr4_0, expr3_0, expr1_0, expr0_0)?;
|
|
let expr6_0 = C::value_reg(ctx, expr5_0);
|
|
return Some(expr6_0);
|
|
}
|
|
&Opcode::Srem => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 497.
|
|
let expr0_0 = constructor_put_in_reg_sext64(ctx, pattern7_0)?;
|
|
let expr1_0 = constructor_put_nonzero_in_reg_sext64(ctx, pattern7_1)?;
|
|
let expr2_0 = ALUOp::SDiv64;
|
|
let expr3_0 = constructor_alu_rrr(ctx, &expr2_0, expr0_0, expr1_0)?;
|
|
let expr4_0 = ALUOp3::MSub64;
|
|
let expr5_0 =
|
|
constructor_alu_rrrr(ctx, &expr4_0, expr3_0, expr1_0, expr0_0)?;
|
|
let expr6_0 = C::value_reg(ctx, expr5_0);
|
|
return Some(expr6_0);
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
&InstructionData::Unary {
|
|
opcode: ref pattern5_0,
|
|
arg: pattern5_1,
|
|
} => {
|
|
match &pattern5_0 {
|
|
&Opcode::Ineg => {
|
|
// Rule at src/isa/aarch64/lower.isle line 186.
|
|
let expr0_0 = constructor_isub_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::zero_reg(ctx);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern5_1);
|
|
let expr3_0 = constructor_alu_rrr(ctx, &expr0_0, expr1_0, expr2_0)?;
|
|
let expr4_0 = C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
&Opcode::Bnot => {
|
|
if let Some(pattern7_0) = C::def_inst(ctx, pattern5_1) {
|
|
let pattern8_0 = C::inst_data(ctx, pattern7_0);
|
|
if let &InstructionData::Binary {
|
|
opcode: ref pattern9_0,
|
|
args: ref pattern9_1,
|
|
} = &pattern8_0
|
|
{
|
|
if let &Opcode::Ishl = &pattern9_0 {
|
|
let (pattern11_0, pattern11_1) =
|
|
C::unpack_value_array_2(ctx, &pattern9_1);
|
|
if let Some(pattern12_0) = C::def_inst(ctx, pattern11_1) {
|
|
let pattern13_0 = C::inst_data(ctx, pattern12_0);
|
|
if let &InstructionData::UnaryImm {
|
|
opcode: ref pattern14_0,
|
|
imm: pattern14_1,
|
|
} = &pattern13_0
|
|
{
|
|
if let &Opcode::Iconst = &pattern14_0 {
|
|
let closure16 = || {
|
|
return Some(pattern3_0);
|
|
};
|
|
if let Some(pattern16_0) = closure16() {
|
|
if let Some(pattern17_0) =
|
|
C::lshl_from_imm64(
|
|
ctx,
|
|
pattern14_1,
|
|
pattern16_0,
|
|
)
|
|
{
|
|
// Rule at src/isa/aarch64/lower.isle line 608.
|
|
let expr0_0 = constructor_orr_not_op(
|
|
ctx, pattern3_0,
|
|
)?;
|
|
let expr1_0 = C::zero_reg(ctx);
|
|
let expr2_0 =
|
|
C::put_in_reg(ctx, pattern11_0);
|
|
let expr3_0 =
|
|
constructor_alu_rrr_shift(
|
|
ctx,
|
|
&expr0_0,
|
|
expr1_0,
|
|
expr2_0,
|
|
pattern17_0,
|
|
)?;
|
|
let expr4_0 =
|
|
C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Rule at src/isa/aarch64/lower.isle line 603.
|
|
let expr0_0 = constructor_orr_not_op(ctx, pattern3_0)?;
|
|
let expr1_0 = C::zero_reg(ctx);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern5_1);
|
|
let expr3_0 = constructor_alu_rrr(ctx, &expr0_0, expr1_0, expr2_0)?;
|
|
let expr4_0 = C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
&Opcode::Uextend => {
|
|
if let Some(pattern7_0) = C::def_inst(ctx, pattern5_1) {
|
|
let pattern8_0 = C::inst_data(ctx, pattern7_0);
|
|
if let &InstructionData::BinaryImm8 {
|
|
opcode: ref pattern9_0,
|
|
arg: pattern9_1,
|
|
imm: pattern9_2,
|
|
} = &pattern8_0
|
|
{
|
|
if let &Opcode::Extractlane = &pattern9_0 {
|
|
let pattern11_0 = C::value_type(ctx, pattern9_1);
|
|
let pattern12_0 = C::u8_from_uimm8(ctx, pattern9_2);
|
|
// Rule at src/isa/aarch64/lower.isle line 515.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern9_1);
|
|
let expr1_0 = constructor_vector_size(ctx, pattern11_0)?;
|
|
let expr2_0 = constructor_mov_from_vec(
|
|
ctx,
|
|
expr0_0,
|
|
pattern12_0,
|
|
&expr1_0,
|
|
)?;
|
|
let expr3_0 = C::value_reg(ctx, expr2_0);
|
|
return Some(expr3_0);
|
|
}
|
|
}
|
|
}
|
|
let pattern7_0 = C::value_type(ctx, pattern5_1);
|
|
if let Some(pattern8_0) = C::sinkable_atomic_load(ctx, pattern5_1) {
|
|
// Rule at src/isa/aarch64/lower.isle line 522.
|
|
let expr0_0 = C::sink_atomic_load(ctx, &pattern8_0);
|
|
let expr1_0 = constructor_load_acquire(ctx, pattern7_0, expr0_0)?;
|
|
let expr2_0 = C::value_reg(ctx, expr1_0);
|
|
return Some(expr2_0);
|
|
}
|
|
// Rule at src/isa/aarch64/lower.isle line 510.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern5_1);
|
|
let expr1_0: bool = false;
|
|
let expr2_0 = C::ty_bits(ctx, pattern7_0);
|
|
let expr3_0 = C::ty_bits(ctx, pattern3_0);
|
|
let expr4_0 =
|
|
constructor_extend(ctx, expr0_0, expr1_0, expr2_0, expr3_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
&Opcode::Sextend => {
|
|
if let Some(pattern7_0) = C::def_inst(ctx, pattern5_1) {
|
|
let pattern8_0 = C::inst_data(ctx, pattern7_0);
|
|
if let &InstructionData::BinaryImm8 {
|
|
opcode: ref pattern9_0,
|
|
arg: pattern9_1,
|
|
imm: pattern9_2,
|
|
} = &pattern8_0
|
|
{
|
|
if let &Opcode::Extractlane = &pattern9_0 {
|
|
let pattern11_0 = C::value_type(ctx, pattern9_1);
|
|
let pattern12_0 = C::u8_from_uimm8(ctx, pattern9_2);
|
|
// Rule at src/isa/aarch64/lower.isle line 547.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern9_1);
|
|
let expr1_0 = constructor_vector_size(ctx, pattern11_0)?;
|
|
let expr2_0 = constructor_size_from_ty(ctx, pattern3_0)?;
|
|
let expr3_0 = constructor_mov_from_vec_signed(
|
|
ctx,
|
|
expr0_0,
|
|
pattern12_0,
|
|
&expr1_0,
|
|
&expr2_0,
|
|
)?;
|
|
let expr4_0 = C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
}
|
|
}
|
|
let pattern7_0 = C::value_type(ctx, pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 542.
|
|
let expr0_0 = C::put_in_reg(ctx, pattern5_1);
|
|
let expr1_0: bool = true;
|
|
let expr2_0 = C::ty_bits(ctx, pattern7_0);
|
|
let expr3_0 = C::ty_bits(ctx, pattern3_0);
|
|
let expr4_0 =
|
|
constructor_extend(ctx, expr0_0, expr1_0, expr2_0, expr3_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
if let Some(pattern3_0) = C::vec128(ctx, pattern2_0) {
|
|
let pattern4_0 = C::inst_data(ctx, pattern0_0);
|
|
match &pattern4_0 {
|
|
&InstructionData::Binary {
|
|
opcode: ref pattern5_0,
|
|
args: ref pattern5_1,
|
|
} => {
|
|
match &pattern5_0 {
|
|
&Opcode::UaddSat => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 165.
|
|
let expr0_0 = VecALUOp::Uqadd;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = constructor_vector_size(ctx, pattern3_0)?;
|
|
let expr4_0 =
|
|
constructor_vec_rrr(ctx, &expr0_0, expr1_0, expr2_0, &expr3_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
&Opcode::SaddSat => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 170.
|
|
let expr0_0 = VecALUOp::Sqadd;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = constructor_vector_size(ctx, pattern3_0)?;
|
|
let expr4_0 =
|
|
constructor_vec_rrr(ctx, &expr0_0, expr1_0, expr2_0, &expr3_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
&Opcode::UsubSat => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 175.
|
|
let expr0_0 = VecALUOp::Uqsub;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = constructor_vector_size(ctx, pattern3_0)?;
|
|
let expr4_0 =
|
|
constructor_vec_rrr(ctx, &expr0_0, expr1_0, expr2_0, &expr3_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
&Opcode::SsubSat => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 180.
|
|
let expr0_0 = VecALUOp::Sqsub;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = constructor_vector_size(ctx, pattern3_0)?;
|
|
let expr4_0 =
|
|
constructor_vec_rrr(ctx, &expr0_0, expr1_0, expr2_0, &expr3_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
&Opcode::Band => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 637.
|
|
let expr0_0 = VecALUOp::And;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = constructor_vector_size(ctx, pattern3_0)?;
|
|
let expr4_0 =
|
|
constructor_vec_rrr(ctx, &expr0_0, expr1_0, expr2_0, &expr3_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
&Opcode::Bor => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 650.
|
|
let expr0_0 = VecALUOp::Orr;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = constructor_vector_size(ctx, pattern3_0)?;
|
|
let expr4_0 =
|
|
constructor_vec_rrr(ctx, &expr0_0, expr1_0, expr2_0, &expr3_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
&Opcode::Bxor => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 663.
|
|
let expr0_0 = VecALUOp::Eor;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = constructor_vector_size(ctx, pattern3_0)?;
|
|
let expr4_0 =
|
|
constructor_vec_rrr(ctx, &expr0_0, expr1_0, expr2_0, &expr3_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
&Opcode::BandNot => {
|
|
let (pattern7_0, pattern7_1) =
|
|
C::unpack_value_array_2(ctx, &pattern5_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 676.
|
|
let expr0_0 = VecALUOp::Bic;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern7_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern7_1);
|
|
let expr3_0 = constructor_vector_size(ctx, pattern3_0)?;
|
|
let expr4_0 =
|
|
constructor_vec_rrr(ctx, &expr0_0, expr1_0, expr2_0, &expr3_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
&InstructionData::Unary {
|
|
opcode: ref pattern5_0,
|
|
arg: pattern5_1,
|
|
} => {
|
|
match &pattern5_0 {
|
|
&Opcode::Ineg => {
|
|
// Rule at src/isa/aarch64/lower.isle line 190.
|
|
let expr0_0 = VecMisc2::Neg;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern5_1);
|
|
let expr2_0 = constructor_vector_size(ctx, pattern3_0)?;
|
|
let expr3_0 = constructor_vec_misc(ctx, &expr0_0, expr1_0, &expr2_0)?;
|
|
let expr4_0 = C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
&Opcode::Bnot => {
|
|
// Rule at src/isa/aarch64/lower.isle line 624.
|
|
let expr0_0 = VecMisc2::Not;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern5_1);
|
|
let expr2_0 = constructor_vector_size(ctx, pattern3_0)?;
|
|
let expr3_0 = constructor_vec_misc(ctx, &expr0_0, expr1_0, &expr2_0)?;
|
|
let expr4_0 = C::value_reg(ctx, expr3_0);
|
|
return Some(expr4_0);
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
if let Some(()) = C::not_i64x2(ctx, pattern3_0) {
|
|
let pattern5_0 = C::inst_data(ctx, pattern0_0);
|
|
if let &InstructionData::Binary {
|
|
opcode: ref pattern6_0,
|
|
args: ref pattern6_1,
|
|
} = &pattern5_0
|
|
{
|
|
if let &Opcode::Imul = &pattern6_0 {
|
|
let (pattern8_0, pattern8_1) = C::unpack_value_array_2(ctx, &pattern6_1);
|
|
// Rule at src/isa/aarch64/lower.isle line 229.
|
|
let expr0_0 = VecALUOp::Mul;
|
|
let expr1_0 = C::put_in_reg(ctx, pattern8_0);
|
|
let expr2_0 = C::put_in_reg(ctx, pattern8_1);
|
|
let expr3_0 = constructor_vector_size(ctx, pattern3_0)?;
|
|
let expr4_0 =
|
|
constructor_vec_rrr(ctx, &expr0_0, expr1_0, expr2_0, &expr3_0)?;
|
|
let expr5_0 = C::value_reg(ctx, expr4_0);
|
|
return Some(expr5_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return None;
|
|
}
|
|
|
|
// Generated as internal constructor for term iadd_op.
|
|
pub fn constructor_iadd_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<ALUOp> {
|
|
let pattern0_0 = arg0;
|
|
if pattern0_0 == I64 {
|
|
// Rule at src/isa/aarch64/lower.isle line 76.
|
|
let expr0_0 = ALUOp::Add64;
|
|
return Some(expr0_0);
|
|
}
|
|
if let Some(pattern1_0) = C::fits_in_32(ctx, pattern0_0) {
|
|
// Rule at src/isa/aarch64/lower.isle line 75.
|
|
let expr0_0 = ALUOp::Add32;
|
|
return Some(expr0_0);
|
|
}
|
|
return None;
|
|
}
|
|
|
|
// Generated as internal constructor for term isub_op.
|
|
pub fn constructor_isub_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<ALUOp> {
|
|
let pattern0_0 = arg0;
|
|
if pattern0_0 == I64 {
|
|
// Rule at src/isa/aarch64/lower.isle line 81.
|
|
let expr0_0 = ALUOp::Sub64;
|
|
return Some(expr0_0);
|
|
}
|
|
if let Some(pattern1_0) = C::fits_in_32(ctx, pattern0_0) {
|
|
// Rule at src/isa/aarch64/lower.isle line 80.
|
|
let expr0_0 = ALUOp::Sub32;
|
|
return Some(expr0_0);
|
|
}
|
|
return None;
|
|
}
|
|
|
|
// Generated as internal constructor for term madd_op.
|
|
pub fn constructor_madd_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<ALUOp3> {
|
|
let pattern0_0 = arg0;
|
|
if pattern0_0 == I64 {
|
|
// Rule at src/isa/aarch64/lower.isle line 86.
|
|
let expr0_0 = ALUOp3::MAdd64;
|
|
return Some(expr0_0);
|
|
}
|
|
if let Some(pattern1_0) = C::fits_in_32(ctx, pattern0_0) {
|
|
// Rule at src/isa/aarch64/lower.isle line 85.
|
|
let expr0_0 = ALUOp3::MAdd32;
|
|
return Some(expr0_0);
|
|
}
|
|
return None;
|
|
}
|
|
|
|
// Generated as internal constructor for term put_nonzero_in_reg_zext64.
|
|
pub fn constructor_put_nonzero_in_reg_zext64<C: Context>(ctx: &mut C, arg0: Value) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = C::value_type(ctx, pattern0_0);
|
|
if let Some(pattern2_0) = C::def_inst(ctx, pattern0_0) {
|
|
let pattern3_0 = C::inst_data(ctx, pattern2_0);
|
|
if let &InstructionData::UnaryImm {
|
|
opcode: ref pattern4_0,
|
|
imm: pattern4_1,
|
|
} = &pattern3_0
|
|
{
|
|
if let &Opcode::Iconst = &pattern4_0 {
|
|
if let Some(pattern6_0) = C::nonzero_u64_from_imm64(ctx, pattern4_1) {
|
|
// Rule at src/isa/aarch64/lower.isle line 420.
|
|
let expr0_0 = constructor_imm(ctx, pattern1_0, pattern6_0)?;
|
|
return Some(expr0_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Rule at src/isa/aarch64/lower.isle line 415.
|
|
let expr0_0 = constructor_put_in_reg_zext64(ctx, pattern0_0)?;
|
|
let expr1_0 = constructor_trap_if_zero_divisor(ctx, expr0_0)?;
|
|
return Some(expr1_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term put_nonzero_in_reg_sext64.
|
|
pub fn constructor_put_nonzero_in_reg_sext64<C: Context>(ctx: &mut C, arg0: Value) -> Option<Reg> {
|
|
let pattern0_0 = arg0;
|
|
let pattern1_0 = C::value_type(ctx, pattern0_0);
|
|
if let Some(pattern2_0) = C::def_inst(ctx, pattern0_0) {
|
|
let pattern3_0 = C::inst_data(ctx, pattern2_0);
|
|
if let &InstructionData::UnaryImm {
|
|
opcode: ref pattern4_0,
|
|
imm: pattern4_1,
|
|
} = &pattern3_0
|
|
{
|
|
if let &Opcode::Iconst = &pattern4_0 {
|
|
if let Some(pattern6_0) = C::nonzero_u64_from_imm64(ctx, pattern4_1) {
|
|
// Rule at src/isa/aarch64/lower.isle line 470.
|
|
let expr0_0 = constructor_imm(ctx, pattern1_0, pattern6_0)?;
|
|
return Some(expr0_0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Rule at src/isa/aarch64/lower.isle line 465.
|
|
let expr0_0 = constructor_put_in_reg_sext64(ctx, pattern0_0)?;
|
|
let expr1_0 = constructor_trap_if_zero_divisor(ctx, expr0_0)?;
|
|
return Some(expr1_0);
|
|
}
|
|
|
|
// Generated as internal constructor for term orr_not_op.
|
|
pub fn constructor_orr_not_op<C: Context>(ctx: &mut C, arg0: Type) -> Option<ALUOp> {
|
|
let pattern0_0 = arg0;
|
|
if pattern0_0 == I64 {
|
|
// Rule at src/isa/aarch64/lower.isle line 596.
|
|
let expr0_0 = ALUOp::OrrNot64;
|
|
return Some(expr0_0);
|
|
}
|
|
if let Some(pattern1_0) = C::fits_in_32(ctx, pattern0_0) {
|
|
// Rule at src/isa/aarch64/lower.isle line 595.
|
|
let expr0_0 = ALUOp::OrrNot32;
|
|
return Some(expr0_0);
|
|
}
|
|
return None;
|
|
}
|