ISLE: Common accessors for some insn data fields (#3781)
Add accessors to prelude.isle to access data fields of
`func_addr` and `symbol_value` instructions.
These are based on similar versions I had added to the s390x
back-end, but are a bit more straightforward to use.
- func_ref_data: Extract SigRef, ExternalName, and RelocDistance
fields given a FuncRef.
- symbol_value_data: Extract ExternalName, RelocDistance, and
offset fields given a GlobalValue representing a Symbol.
- reloc_distance_near: Test for RelocDistance::Near.
The s390x back-end is changed to use these common versions.
Note that this exposed a bug in common isle code: This extractor:
(extractor (load_sym inst)
(and inst
(load _ (def_inst (symbol_value
(symbol_value_data _
(reloc_distance_near) offset)))
(i64_from_offset
(memarg_symbol_offset_sum <offset _)))))
would raise an assertion in sema.rs due to a supposed cycle in
extractor definitions. But there was no actual cycle, it was
simply that the extractor tree refers twice to the `insn_data`
extractor (once via the `load` and once via the `symbol_value`
extractor). Fixed by checking for pre-existing definitions only
along one path in the tree, not across the whole tree.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
src/clif.isle 9ea75a6f790b5c03
|
src/clif.isle 9ea75a6f790b5c03
|
||||||
src/prelude.isle 6aaf8ce0f5a5c2ec
|
src/prelude.isle 73285cd431346d53
|
||||||
src/isa/aarch64/inst.isle dafd813ba278ce19
|
src/isa/aarch64/inst.isle dafd813ba278ce19
|
||||||
src/isa/aarch64/lower.isle 2d2e1e076a0c8a23
|
src/isa/aarch64/lower.isle 2d2e1e076a0c8a23
|
||||||
|
|||||||
@@ -65,6 +65,12 @@ pub trait Context {
|
|||||||
fn trap_code_integer_overflow(&mut self) -> TrapCode;
|
fn trap_code_integer_overflow(&mut self) -> TrapCode;
|
||||||
fn trap_code_bad_conversion_to_integer(&mut self) -> TrapCode;
|
fn trap_code_bad_conversion_to_integer(&mut self) -> TrapCode;
|
||||||
fn avoid_div_traps(&mut self, arg0: Type) -> Option<()>;
|
fn avoid_div_traps(&mut self, arg0: Type) -> Option<()>;
|
||||||
|
fn func_ref_data(&mut self, arg0: FuncRef) -> (SigRef, ExternalName, RelocDistance);
|
||||||
|
fn symbol_value_data(
|
||||||
|
&mut self,
|
||||||
|
arg0: GlobalValue,
|
||||||
|
) -> Option<(ExternalName, RelocDistance, i64)>;
|
||||||
|
fn reloc_distance_near(&mut self, arg0: RelocDistance) -> Option<()>;
|
||||||
fn move_wide_const_from_u64(&mut self, arg0: u64) -> Option<MoveWideConst>;
|
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 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_u64(&mut self, arg0: u64, arg1: Type) -> Option<ImmLogic>;
|
||||||
@@ -96,19 +102,19 @@ pub trait Context {
|
|||||||
fn rotr_opposite_amount(&mut self, arg0: Type, arg1: ImmShift) -> ImmShift;
|
fn rotr_opposite_amount(&mut self, arg0: Type, arg1: ImmShift) -> ImmShift;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal type SideEffectNoResult: defined at src/prelude.isle line 307.
|
/// Internal type SideEffectNoResult: defined at src/prelude.isle line 308.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum SideEffectNoResult {
|
pub enum SideEffectNoResult {
|
||||||
Inst { inst: MInst },
|
Inst { inst: MInst },
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal type ProducesFlags: defined at src/prelude.isle line 326.
|
/// Internal type ProducesFlags: defined at src/prelude.isle line 327.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum ProducesFlags {
|
pub enum ProducesFlags {
|
||||||
ProducesFlags { inst: MInst, result: Reg },
|
ProducesFlags { inst: MInst, result: Reg },
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal type ConsumesFlags: defined at src/prelude.isle line 329.
|
/// Internal type ConsumesFlags: defined at src/prelude.isle line 330.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum ConsumesFlags {
|
pub enum ConsumesFlags {
|
||||||
ConsumesFlags { inst: MInst, result: Reg },
|
ConsumesFlags { inst: MInst, result: Reg },
|
||||||
@@ -1019,7 +1025,7 @@ pub fn constructor_value_regs_none<C: Context>(
|
|||||||
inst: ref pattern1_0,
|
inst: ref pattern1_0,
|
||||||
} = pattern0_0
|
} = pattern0_0
|
||||||
{
|
{
|
||||||
// Rule at src/prelude.isle line 312.
|
// Rule at src/prelude.isle line 313.
|
||||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||||
let expr1_0 = C::value_regs_invalid(ctx);
|
let expr1_0 = C::value_regs_invalid(ctx);
|
||||||
return Some(expr1_0);
|
return Some(expr1_0);
|
||||||
@@ -1037,7 +1043,7 @@ pub fn constructor_safepoint<C: Context>(
|
|||||||
inst: ref pattern1_0,
|
inst: ref pattern1_0,
|
||||||
} = pattern0_0
|
} = pattern0_0
|
||||||
{
|
{
|
||||||
// Rule at src/prelude.isle line 318.
|
// Rule at src/prelude.isle line 319.
|
||||||
let expr0_0 = C::emit_safepoint(ctx, &pattern1_0);
|
let expr0_0 = C::emit_safepoint(ctx, &pattern1_0);
|
||||||
let expr1_0 = C::value_regs_invalid(ctx);
|
let expr1_0 = C::value_regs_invalid(ctx);
|
||||||
return Some(expr1_0);
|
return Some(expr1_0);
|
||||||
@@ -1063,7 +1069,7 @@ pub fn constructor_with_flags<C: Context>(
|
|||||||
result: pattern3_1,
|
result: pattern3_1,
|
||||||
} = pattern2_0
|
} = pattern2_0
|
||||||
{
|
{
|
||||||
// Rule at src/prelude.isle line 339.
|
// Rule at src/prelude.isle line 340.
|
||||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||||
let expr1_0 = C::emit(ctx, &pattern3_0);
|
let expr1_0 = C::emit(ctx, &pattern3_0);
|
||||||
let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1);
|
let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1);
|
||||||
@@ -1091,7 +1097,7 @@ pub fn constructor_with_flags_1<C: Context>(
|
|||||||
result: pattern3_1,
|
result: pattern3_1,
|
||||||
} = pattern2_0
|
} = pattern2_0
|
||||||
{
|
{
|
||||||
// Rule at src/prelude.isle line 347.
|
// Rule at src/prelude.isle line 348.
|
||||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||||
let expr1_0 = C::emit(ctx, &pattern3_0);
|
let expr1_0 = C::emit(ctx, &pattern3_0);
|
||||||
return Some(pattern3_1);
|
return Some(pattern3_1);
|
||||||
@@ -1125,7 +1131,7 @@ pub fn constructor_with_flags_2<C: Context>(
|
|||||||
result: pattern5_1,
|
result: pattern5_1,
|
||||||
} = pattern4_0
|
} = pattern4_0
|
||||||
{
|
{
|
||||||
// Rule at src/prelude.isle line 357.
|
// Rule at src/prelude.isle line 358.
|
||||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||||
let expr1_0 = C::emit(ctx, &pattern5_0);
|
let expr1_0 = C::emit(ctx, &pattern5_0);
|
||||||
let expr2_0 = C::emit(ctx, &pattern3_0);
|
let expr2_0 = C::emit(ctx, &pattern3_0);
|
||||||
|
|||||||
@@ -904,19 +904,6 @@
|
|||||||
(extern extractor allow_div_traps allow_div_traps)
|
(extern extractor allow_div_traps allow_div_traps)
|
||||||
|
|
||||||
|
|
||||||
;; Helpers to access instruction data members ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;; Extractor for `symbol_value` instruction data member.
|
|
||||||
|
|
||||||
(decl symbol_value_data (BoxExternalName RelocDistance i64) Inst)
|
|
||||||
(extern extractor symbol_value_data symbol_value_data)
|
|
||||||
|
|
||||||
;; Extractor for `call_target` instruction data members.
|
|
||||||
|
|
||||||
(decl call_target_data (BoxExternalName RelocDistance) Inst)
|
|
||||||
(extern extractor call_target_data call_target_data)
|
|
||||||
|
|
||||||
|
|
||||||
;; Helpers for register numbers and types ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;; Helpers for register numbers and types ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
;; Hard-coded registers.
|
;; Hard-coded registers.
|
||||||
@@ -1090,13 +1077,6 @@
|
|||||||
|
|
||||||
;; Helpers for memory arguments ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;; Helpers for memory arguments ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
;; Accessors for `RelocDistance`.
|
|
||||||
|
|
||||||
(type RelocDistance extern (enum))
|
|
||||||
|
|
||||||
(decl reloc_distance_near () RelocDistance)
|
|
||||||
(extern extractor reloc_distance_near reloc_distance_near)
|
|
||||||
|
|
||||||
;; Accessors for `Offset32`.
|
;; Accessors for `Offset32`.
|
||||||
|
|
||||||
(decl zero_offset () Offset32)
|
(decl zero_offset () Offset32)
|
||||||
@@ -1105,6 +1085,11 @@
|
|||||||
(decl i64_from_offset (i64) Offset32)
|
(decl i64_from_offset (i64) Offset32)
|
||||||
(extern extractor infallible i64_from_offset i64_from_offset)
|
(extern extractor infallible i64_from_offset i64_from_offset)
|
||||||
|
|
||||||
|
;; Accessors for `ExternalName`.
|
||||||
|
|
||||||
|
(decl box_external_name (ExternalName) BoxExternalName)
|
||||||
|
(extern constructor box_external_name box_external_name)
|
||||||
|
|
||||||
;; Accessors for `MemFlags`.
|
;; Accessors for `MemFlags`.
|
||||||
|
|
||||||
(decl littleendian () MemFlags)
|
(decl littleendian () MemFlags)
|
||||||
@@ -1126,7 +1111,7 @@
|
|||||||
(decl memarg_reg_plus_off (Reg i64 MemFlags) MemArg)
|
(decl memarg_reg_plus_off (Reg i64 MemFlags) MemArg)
|
||||||
(extern constructor memarg_reg_plus_off memarg_reg_plus_off)
|
(extern constructor memarg_reg_plus_off memarg_reg_plus_off)
|
||||||
|
|
||||||
(decl memarg_symbol (BoxExternalName i32 MemFlags) MemArg)
|
(decl memarg_symbol (ExternalName i32 MemFlags) MemArg)
|
||||||
(extern constructor memarg_symbol memarg_symbol)
|
(extern constructor memarg_symbol memarg_symbol)
|
||||||
|
|
||||||
;; Form the sum of two offset values, and check that the result is
|
;; Form the sum of two offset values, and check that the result is
|
||||||
@@ -1149,7 +1134,7 @@
|
|||||||
(memarg_reg_plus_reg (put_in_reg x) (put_in_reg y) flags))
|
(memarg_reg_plus_reg (put_in_reg x) (put_in_reg y) flags))
|
||||||
|
|
||||||
(rule (lower_address flags
|
(rule (lower_address flags
|
||||||
(def_inst (symbol_value_data name (reloc_distance_near) offset))
|
(def_inst (symbol_value (symbol_value_data name (reloc_distance_near) offset)))
|
||||||
(i64_from_offset (memarg_symbol_offset_sum <offset final_offset)))
|
(i64_from_offset (memarg_symbol_offset_sum <offset final_offset)))
|
||||||
(memarg_symbol name final_offset flags))
|
(memarg_symbol name final_offset flags))
|
||||||
|
|
||||||
@@ -1159,13 +1144,13 @@
|
|||||||
(decl load_sym (Inst) Inst)
|
(decl load_sym (Inst) Inst)
|
||||||
(extractor (load_sym inst)
|
(extractor (load_sym inst)
|
||||||
(and inst
|
(and inst
|
||||||
(load _ (def_inst (symbol_value_data _ (reloc_distance_near) offset))
|
(load _ (def_inst (symbol_value (symbol_value_data _ (reloc_distance_near) offset)))
|
||||||
(i64_from_offset (memarg_symbol_offset_sum <offset _)))))
|
(i64_from_offset (memarg_symbol_offset_sum <offset _)))))
|
||||||
|
|
||||||
(decl uload16_sym (Inst) Inst)
|
(decl uload16_sym (Inst) Inst)
|
||||||
(extractor (uload16_sym inst)
|
(extractor (uload16_sym inst)
|
||||||
(and inst
|
(and inst
|
||||||
(uload16 _ (def_inst (symbol_value_data _ (reloc_distance_near) offset))
|
(uload16 _ (def_inst (symbol_value (symbol_value_data _ (reloc_distance_near) offset)))
|
||||||
(i64_from_offset (memarg_symbol_offset_sum <offset _)))))
|
(i64_from_offset (memarg_symbol_offset_sum <offset _)))))
|
||||||
|
|
||||||
|
|
||||||
@@ -1730,10 +1715,11 @@
|
|||||||
(SideEffectNoResult.Inst (MInst.FpuStoreRev64 src addr)))
|
(SideEffectNoResult.Inst (MInst.FpuStoreRev64 src addr)))
|
||||||
|
|
||||||
;; Helper for emitting `MInst.LoadExtNameFar` instructions.
|
;; Helper for emitting `MInst.LoadExtNameFar` instructions.
|
||||||
(decl load_ext_name_far (BoxExternalName i64) Reg)
|
(decl load_ext_name_far (ExternalName i64) Reg)
|
||||||
(rule (load_ext_name_far name offset)
|
(rule (load_ext_name_far name offset)
|
||||||
(let ((dst WritableReg (temp_writable_reg $I64))
|
(let ((dst WritableReg (temp_writable_reg $I64))
|
||||||
(_ Unit (emit (MInst.LoadExtNameFar dst name offset))))
|
(boxed_name BoxExternalName (box_external_name name))
|
||||||
|
(_ Unit (emit (MInst.LoadExtNameFar dst boxed_name offset))))
|
||||||
(writable_reg_to_reg dst)))
|
(writable_reg_to_reg dst)))
|
||||||
|
|
||||||
;; Helper for emitting `MInst.LoadAddr` instructions.
|
;; Helper for emitting `MInst.LoadAddr` instructions.
|
||||||
|
|||||||
@@ -1156,27 +1156,23 @@
|
|||||||
;;;; Rules for `func_addr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;; Rules for `func_addr` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
;; Load the address of a function, target reachable via PC-relative instruction.
|
;; Load the address of a function, target reachable via PC-relative instruction.
|
||||||
(rule (lower (and (func_addr _)
|
(rule (lower (func_addr (func_ref_data _ name (reloc_distance_near))))
|
||||||
(call_target_data name (reloc_distance_near))))
|
|
||||||
(value_reg (load_addr (memarg_symbol name 0 (memflags_trusted)))))
|
(value_reg (load_addr (memarg_symbol name 0 (memflags_trusted)))))
|
||||||
|
|
||||||
;; Load the address of a function, general case.
|
;; Load the address of a function, general case.
|
||||||
(rule (lower (and (func_addr _)
|
(rule (lower (func_addr (func_ref_data _ name _)))
|
||||||
(call_target_data name _)))
|
|
||||||
(value_reg (load_ext_name_far name 0)))
|
(value_reg (load_ext_name_far name 0)))
|
||||||
|
|
||||||
|
|
||||||
;;;; Rules for `symbol_value` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;; Rules for `symbol_value` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
;; Load the address of a symbol, target reachable via PC-relative instruction.
|
;; Load the address of a symbol, target reachable via PC-relative instruction.
|
||||||
(rule (lower (and (symbol_value _)
|
(rule (lower (symbol_value (symbol_value_data name (reloc_distance_near)
|
||||||
(symbol_value_data name (reloc_distance_near)
|
(memarg_symbol_offset offset))))
|
||||||
(memarg_symbol_offset offset))))
|
|
||||||
(value_reg (load_addr (memarg_symbol name offset (memflags_trusted)))))
|
(value_reg (load_addr (memarg_symbol name offset (memflags_trusted)))))
|
||||||
|
|
||||||
;; Load the address of a symbol, general case.
|
;; Load the address of a symbol, general case.
|
||||||
(rule (lower (and (symbol_value _)
|
(rule (lower (symbol_value (symbol_value_data name _ offset)))
|
||||||
(symbol_value_data name _ offset)))
|
|
||||||
(value_reg (load_ext_name_far name offset)))
|
(value_reg (load_ext_name_far name offset)))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ use crate::machinst::isle::*;
|
|||||||
use crate::settings::Flags;
|
use crate::settings::Flags;
|
||||||
use crate::{
|
use crate::{
|
||||||
ir::{
|
ir::{
|
||||||
condcodes::*, immediates::*, types::*, AtomicRmwOp, Endianness, ExternalName, Inst,
|
condcodes::*, immediates::*, types::*, AtomicRmwOp, Endianness, Inst, InstructionData,
|
||||||
InstructionData, StackSlot, TrapCode, Value, ValueLabel, ValueList,
|
StackSlot, TrapCode, Value, ValueLabel, ValueList,
|
||||||
},
|
},
|
||||||
isa::s390x::inst::s390x_map_regs,
|
isa::s390x::inst::s390x_map_regs,
|
||||||
isa::unwind::UnwindInst,
|
isa::unwind::UnwindInst,
|
||||||
machinst::{InsnOutput, LowerCtx, RelocDistance},
|
machinst::{InsnOutput, LowerCtx},
|
||||||
};
|
};
|
||||||
use std::boxed::Box;
|
use std::boxed::Box;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
@@ -127,18 +127,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn symbol_value_data(&mut self, inst: Inst) -> Option<(BoxExternalName, RelocDistance, i64)> {
|
|
||||||
let (name, dist, offset) = self.lower_ctx.symbol_value(inst)?;
|
|
||||||
Some((Box::new(name.clone()), dist, offset))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn call_target_data(&mut self, inst: Inst) -> Option<(BoxExternalName, RelocDistance)> {
|
|
||||||
let (name, dist) = self.lower_ctx.call_target(inst)?;
|
|
||||||
Some((Box::new(name.clone()), dist))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn writable_gpr(&mut self, regno: u8) -> WritableReg {
|
fn writable_gpr(&mut self, regno: u8) -> WritableReg {
|
||||||
super::writable_gpr(regno)
|
super::writable_gpr(regno)
|
||||||
@@ -404,15 +392,6 @@ where
|
|||||||
vec[usize::from(index)]
|
vec[usize::from(index)]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn reloc_distance_near(&mut self, dist: &RelocDistance) -> Option<()> {
|
|
||||||
if *dist == RelocDistance::Near {
|
|
||||||
Some(())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn zero_offset(&mut self) -> Offset32 {
|
fn zero_offset(&mut self) -> Offset32 {
|
||||||
Offset32::new(0)
|
Offset32::new(0)
|
||||||
@@ -443,6 +422,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn box_external_name(&mut self, name: ExternalName) -> BoxExternalName {
|
||||||
|
Box::new(name)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn memflags_trusted(&mut self) -> MemFlags {
|
fn memflags_trusted(&mut self) -> MemFlags {
|
||||||
MemFlags::trusted()
|
MemFlags::trusted()
|
||||||
@@ -459,9 +443,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn memarg_symbol(&mut self, name: BoxExternalName, offset: i32, flags: MemFlags) -> MemArg {
|
fn memarg_symbol(&mut self, name: ExternalName, offset: i32, flags: MemFlags) -> MemArg {
|
||||||
MemArg::Symbol {
|
MemArg::Symbol {
|
||||||
name,
|
name: Box::new(name),
|
||||||
offset,
|
offset,
|
||||||
flags,
|
flags,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
src/clif.isle 9ea75a6f790b5c03
|
src/clif.isle 9ea75a6f790b5c03
|
||||||
src/prelude.isle 6aaf8ce0f5a5c2ec
|
src/prelude.isle 73285cd431346d53
|
||||||
src/isa/s390x/inst.isle 1ae3c0f9c956affd
|
src/isa/s390x/inst.isle 87a2d7c0c69d0324
|
||||||
src/isa/s390x/lower.isle d18ee0bff12cad4e
|
src/isa/s390x/lower.isle 3c124e26bc411983
|
||||||
|
|||||||
1600
cranelift/codegen/src/isa/s390x/lower/isle/generated_code.rs
generated
1600
cranelift/codegen/src/isa/s390x/lower/isle/generated_code.rs
generated
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
src/clif.isle 9ea75a6f790b5c03
|
src/clif.isle 9ea75a6f790b5c03
|
||||||
src/prelude.isle 6aaf8ce0f5a5c2ec
|
src/prelude.isle 73285cd431346d53
|
||||||
src/isa/x64/inst.isle 7513533d16948249
|
src/isa/x64/inst.isle 7513533d16948249
|
||||||
src/isa/x64/lower.isle 976ac116c5fcfa16
|
src/isa/x64/lower.isle 976ac116c5fcfa16
|
||||||
|
|||||||
@@ -65,6 +65,12 @@ pub trait Context {
|
|||||||
fn trap_code_integer_overflow(&mut self) -> TrapCode;
|
fn trap_code_integer_overflow(&mut self) -> TrapCode;
|
||||||
fn trap_code_bad_conversion_to_integer(&mut self) -> TrapCode;
|
fn trap_code_bad_conversion_to_integer(&mut self) -> TrapCode;
|
||||||
fn avoid_div_traps(&mut self, arg0: Type) -> Option<()>;
|
fn avoid_div_traps(&mut self, arg0: Type) -> Option<()>;
|
||||||
|
fn func_ref_data(&mut self, arg0: FuncRef) -> (SigRef, ExternalName, RelocDistance);
|
||||||
|
fn symbol_value_data(
|
||||||
|
&mut self,
|
||||||
|
arg0: GlobalValue,
|
||||||
|
) -> Option<(ExternalName, RelocDistance, i64)>;
|
||||||
|
fn reloc_distance_near(&mut self, arg0: RelocDistance) -> Option<()>;
|
||||||
fn operand_size_of_type_32_64(&mut self, arg0: Type) -> OperandSize;
|
fn operand_size_of_type_32_64(&mut self, arg0: Type) -> OperandSize;
|
||||||
fn raw_operand_size_of_type(&mut self, arg0: Type) -> OperandSize;
|
fn raw_operand_size_of_type(&mut self, arg0: Type) -> OperandSize;
|
||||||
fn put_in_reg_mem_imm(&mut self, arg0: Value) -> RegMemImm;
|
fn put_in_reg_mem_imm(&mut self, arg0: Value) -> RegMemImm;
|
||||||
@@ -113,19 +119,19 @@ pub trait Context {
|
|||||||
fn sse_insertps_lane_imm(&mut self, arg0: u8) -> u8;
|
fn sse_insertps_lane_imm(&mut self, arg0: u8) -> u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal type SideEffectNoResult: defined at src/prelude.isle line 307.
|
/// Internal type SideEffectNoResult: defined at src/prelude.isle line 308.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum SideEffectNoResult {
|
pub enum SideEffectNoResult {
|
||||||
Inst { inst: MInst },
|
Inst { inst: MInst },
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal type ProducesFlags: defined at src/prelude.isle line 326.
|
/// Internal type ProducesFlags: defined at src/prelude.isle line 327.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum ProducesFlags {
|
pub enum ProducesFlags {
|
||||||
ProducesFlags { inst: MInst, result: Reg },
|
ProducesFlags { inst: MInst, result: Reg },
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal type ConsumesFlags: defined at src/prelude.isle line 329.
|
/// Internal type ConsumesFlags: defined at src/prelude.isle line 330.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum ConsumesFlags {
|
pub enum ConsumesFlags {
|
||||||
ConsumesFlags { inst: MInst, result: Reg },
|
ConsumesFlags { inst: MInst, result: Reg },
|
||||||
@@ -478,7 +484,7 @@ pub fn constructor_value_regs_none<C: Context>(
|
|||||||
inst: ref pattern1_0,
|
inst: ref pattern1_0,
|
||||||
} = pattern0_0
|
} = pattern0_0
|
||||||
{
|
{
|
||||||
// Rule at src/prelude.isle line 312.
|
// Rule at src/prelude.isle line 313.
|
||||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||||
let expr1_0 = C::value_regs_invalid(ctx);
|
let expr1_0 = C::value_regs_invalid(ctx);
|
||||||
return Some(expr1_0);
|
return Some(expr1_0);
|
||||||
@@ -496,7 +502,7 @@ pub fn constructor_safepoint<C: Context>(
|
|||||||
inst: ref pattern1_0,
|
inst: ref pattern1_0,
|
||||||
} = pattern0_0
|
} = pattern0_0
|
||||||
{
|
{
|
||||||
// Rule at src/prelude.isle line 318.
|
// Rule at src/prelude.isle line 319.
|
||||||
let expr0_0 = C::emit_safepoint(ctx, &pattern1_0);
|
let expr0_0 = C::emit_safepoint(ctx, &pattern1_0);
|
||||||
let expr1_0 = C::value_regs_invalid(ctx);
|
let expr1_0 = C::value_regs_invalid(ctx);
|
||||||
return Some(expr1_0);
|
return Some(expr1_0);
|
||||||
@@ -522,7 +528,7 @@ pub fn constructor_with_flags<C: Context>(
|
|||||||
result: pattern3_1,
|
result: pattern3_1,
|
||||||
} = pattern2_0
|
} = pattern2_0
|
||||||
{
|
{
|
||||||
// Rule at src/prelude.isle line 339.
|
// Rule at src/prelude.isle line 340.
|
||||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||||
let expr1_0 = C::emit(ctx, &pattern3_0);
|
let expr1_0 = C::emit(ctx, &pattern3_0);
|
||||||
let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1);
|
let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1);
|
||||||
@@ -550,7 +556,7 @@ pub fn constructor_with_flags_1<C: Context>(
|
|||||||
result: pattern3_1,
|
result: pattern3_1,
|
||||||
} = pattern2_0
|
} = pattern2_0
|
||||||
{
|
{
|
||||||
// Rule at src/prelude.isle line 347.
|
// Rule at src/prelude.isle line 348.
|
||||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||||
let expr1_0 = C::emit(ctx, &pattern3_0);
|
let expr1_0 = C::emit(ctx, &pattern3_0);
|
||||||
return Some(pattern3_1);
|
return Some(pattern3_1);
|
||||||
@@ -584,7 +590,7 @@ pub fn constructor_with_flags_2<C: Context>(
|
|||||||
result: pattern5_1,
|
result: pattern5_1,
|
||||||
} = pattern4_0
|
} = pattern4_0
|
||||||
{
|
{
|
||||||
// Rule at src/prelude.isle line 357.
|
// Rule at src/prelude.isle line 358.
|
||||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||||
let expr1_0 = C::emit(ctx, &pattern5_0);
|
let expr1_0 = C::emit(ctx, &pattern5_0);
|
||||||
let expr2_0 = C::emit(ctx, &pattern3_0);
|
let expr2_0 = C::emit(ctx, &pattern3_0);
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ use regalloc::{Reg, Writable};
|
|||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
pub use super::MachLabel;
|
pub use super::MachLabel;
|
||||||
pub use crate::ir::ExternalName;
|
pub use crate::ir::{ExternalName, FuncRef, GlobalValue, SigRef};
|
||||||
pub use crate::isa::unwind::UnwindInst;
|
pub use crate::isa::unwind::UnwindInst;
|
||||||
|
pub use crate::machinst::RelocDistance;
|
||||||
|
|
||||||
pub type Unit = ();
|
pub type Unit = ();
|
||||||
pub type ValueSlice<'a> = &'a [Value];
|
pub type ValueSlice<'a> = &'a [Value];
|
||||||
@@ -282,6 +283,34 @@ macro_rules! isle_prelude_methods {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn func_ref_data(&mut self, func_ref: FuncRef) -> (SigRef, ExternalName, RelocDistance) {
|
||||||
|
let funcdata = &self.lower_ctx.dfg().ext_funcs[func_ref];
|
||||||
|
(
|
||||||
|
funcdata.signature,
|
||||||
|
funcdata.name.clone(),
|
||||||
|
funcdata.reloc_distance(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn symbol_value_data(
|
||||||
|
&mut self,
|
||||||
|
global_value: GlobalValue,
|
||||||
|
) -> Option<(ExternalName, RelocDistance, i64)> {
|
||||||
|
let (name, reloc, offset) = self.lower_ctx.symbol_value_data(global_value)?;
|
||||||
|
Some((name.clone(), reloc, offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn reloc_distance_near(&mut self, dist: RelocDistance) -> Option<()> {
|
||||||
|
if dist == RelocDistance::Near {
|
||||||
|
Some(())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn nonzero_u64_from_imm64(&mut self, val: Imm64) -> Option<u64> {
|
fn nonzero_u64_from_imm64(&mut self, val: Imm64) -> Option<u64> {
|
||||||
match val.bits() {
|
match val.bits() {
|
||||||
0 => None,
|
0 => None,
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ use crate::ir::instructions::BranchInfo;
|
|||||||
use crate::ir::{
|
use crate::ir::{
|
||||||
types::{FFLAGS, IFLAGS},
|
types::{FFLAGS, IFLAGS},
|
||||||
ArgumentPurpose, Block, Constant, ConstantData, DataFlowGraph, ExternalName, Function,
|
ArgumentPurpose, Block, Constant, ConstantData, DataFlowGraph, ExternalName, Function,
|
||||||
GlobalValueData, Inst, InstructionData, MemFlags, Opcode, Signature, SourceLoc, Type, Value,
|
GlobalValue, GlobalValueData, Inst, InstructionData, MemFlags, Opcode, Signature, SourceLoc,
|
||||||
ValueDef, ValueLabelAssignments, ValueLabelStart,
|
Type, Value, ValueDef, ValueLabelAssignments, ValueLabelStart,
|
||||||
};
|
};
|
||||||
use crate::machinst::{
|
use crate::machinst::{
|
||||||
non_writable_value_regs, writable_value_regs, ABICallee, BlockIndex, BlockLoweringOrder,
|
non_writable_value_regs, writable_value_regs, ABICallee, BlockIndex, BlockLoweringOrder,
|
||||||
@@ -93,6 +93,11 @@ pub trait LowerCtx {
|
|||||||
/// Get the symbol name, relocation distance estimate, and offset for a
|
/// Get the symbol name, relocation distance estimate, and offset for a
|
||||||
/// symbol_value instruction.
|
/// symbol_value instruction.
|
||||||
fn symbol_value<'b>(&'b self, ir_inst: Inst) -> Option<(&'b ExternalName, RelocDistance, i64)>;
|
fn symbol_value<'b>(&'b self, ir_inst: Inst) -> Option<(&'b ExternalName, RelocDistance, i64)>;
|
||||||
|
/// Likewise, but starting with a GlobalValue identifier.
|
||||||
|
fn symbol_value_data<'b>(
|
||||||
|
&'b self,
|
||||||
|
global_value: GlobalValue,
|
||||||
|
) -> Option<(&'b ExternalName, RelocDistance, i64)>;
|
||||||
/// Returns the memory flags of a given memory access.
|
/// Returns the memory flags of a given memory access.
|
||||||
fn memflags(&self, ir_inst: Inst) -> Option<MemFlags>;
|
fn memflags(&self, ir_inst: Inst) -> Option<MemFlags>;
|
||||||
/// Get the source location for a given instruction.
|
/// Get the source location for a given instruction.
|
||||||
@@ -1070,19 +1075,26 @@ impl<'func, I: VCodeInst> LowerCtx for Lower<'func, I> {
|
|||||||
fn symbol_value<'b>(&'b self, ir_inst: Inst) -> Option<(&'b ExternalName, RelocDistance, i64)> {
|
fn symbol_value<'b>(&'b self, ir_inst: Inst) -> Option<(&'b ExternalName, RelocDistance, i64)> {
|
||||||
match &self.f.dfg[ir_inst] {
|
match &self.f.dfg[ir_inst] {
|
||||||
&InstructionData::UnaryGlobalValue { global_value, .. } => {
|
&InstructionData::UnaryGlobalValue { global_value, .. } => {
|
||||||
let gvdata = &self.f.global_values[global_value];
|
self.symbol_value_data(global_value)
|
||||||
match gvdata {
|
}
|
||||||
&GlobalValueData::Symbol {
|
_ => None,
|
||||||
ref name,
|
}
|
||||||
ref offset,
|
}
|
||||||
..
|
|
||||||
} => {
|
fn symbol_value_data<'b>(
|
||||||
let offset = offset.bits();
|
&'b self,
|
||||||
let dist = gvdata.maybe_reloc_distance().unwrap();
|
global_value: GlobalValue,
|
||||||
Some((name, dist, offset))
|
) -> Option<(&'b ExternalName, RelocDistance, i64)> {
|
||||||
}
|
let gvdata = &self.f.global_values[global_value];
|
||||||
_ => None,
|
match gvdata {
|
||||||
}
|
&GlobalValueData::Symbol {
|
||||||
|
ref name,
|
||||||
|
ref offset,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let offset = offset.bits();
|
||||||
|
let dist = gvdata.maybe_reloc_distance().unwrap();
|
||||||
|
Some((name, dist, offset))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,6 +117,7 @@
|
|||||||
(type UnwindInst (primitive UnwindInst))
|
(type UnwindInst (primitive UnwindInst))
|
||||||
(type ExternalName (primitive ExternalName))
|
(type ExternalName (primitive ExternalName))
|
||||||
(type BoxExternalName (primitive BoxExternalName))
|
(type BoxExternalName (primitive BoxExternalName))
|
||||||
|
(type RelocDistance (primitive RelocDistance))
|
||||||
|
|
||||||
;;;; Primitive Type Conversions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;; Primitive Type Conversions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
@@ -380,3 +381,22 @@
|
|||||||
|
|
||||||
(decl avoid_div_traps () Type)
|
(decl avoid_div_traps () Type)
|
||||||
(extern extractor avoid_div_traps avoid_div_traps)
|
(extern extractor avoid_div_traps avoid_div_traps)
|
||||||
|
|
||||||
|
;;;; Helpers for accessing instruction data ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; Accessor for `FuncRef`.
|
||||||
|
|
||||||
|
(decl func_ref_data (SigRef ExternalName RelocDistance) FuncRef)
|
||||||
|
(extern extractor infallible func_ref_data func_ref_data)
|
||||||
|
|
||||||
|
;; Accessor for `GobalValue`.
|
||||||
|
|
||||||
|
(decl symbol_value_data (ExternalName RelocDistance i64) GlobalValue)
|
||||||
|
(extern extractor symbol_value_data symbol_value_data)
|
||||||
|
|
||||||
|
;; Accessor for `RelocDistance`.
|
||||||
|
|
||||||
|
(decl reloc_distance_near () RelocDistance)
|
||||||
|
(extern extractor reloc_distance_near reloc_distance_near)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1034,21 +1034,19 @@ impl TermEnv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for cycles in the extractor call graph.
|
// Check for cycles in the extractor call graph.
|
||||||
let mut seen = BTreeSet::new();
|
|
||||||
let mut stack = vec![];
|
let mut stack = vec![];
|
||||||
'outer: for root in extractor_call_graph.keys().copied() {
|
'outer: for root in extractor_call_graph.keys().copied() {
|
||||||
seen.clear();
|
|
||||||
stack.clear();
|
stack.clear();
|
||||||
stack.push((root, vec![root]));
|
stack.push((root, vec![root], BTreeSet::new()));
|
||||||
|
|
||||||
while let Some((caller, path)) = stack.pop() {
|
while let Some((caller, path, mut seen)) = stack.pop() {
|
||||||
let is_new = seen.insert(caller);
|
let is_new = seen.insert(caller);
|
||||||
if is_new {
|
if is_new {
|
||||||
if let Some(callees) = extractor_call_graph.get(&caller) {
|
if let Some(callees) = extractor_call_graph.get(&caller) {
|
||||||
stack.extend(callees.iter().map(|callee| {
|
stack.extend(callees.iter().map(|callee| {
|
||||||
let mut path = path.clone();
|
let mut path = path.clone();
|
||||||
path.push(*callee);
|
path.push(*callee);
|
||||||
(*callee, path)
|
(*callee, path, seen.clone())
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user