Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit 486e40b

Browse files
committed
Legalize load.i128 and store.i128 with arbitrary offsets
1 parent 0d46b36 commit 486e40b

File tree

3 files changed

+69
-31
lines changed

3 files changed

+69
-31
lines changed

cranelift-codegen/meta/src/shared/legalize.rs

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ pub fn define(insts: &InstructionGroup, immediates: &OperandKinds) -> TransformG
148148
let ieee32 = immediates.by_name("ieee32");
149149
let ieee64 = immediates.by_name("ieee64");
150150
let intcc = immediates.by_name("intcc");
151-
let offset32 = immediates.by_name("offset32");
152151

153152
// List of variables to reuse in patterns.
154153
let x = var("x");
@@ -287,29 +286,8 @@ pub fn define(insts: &InstructionGroup, immediates: &OperandKinds) -> TransformG
287286
],
288287
);
289288

290-
// FIXME generalize to any offset once offset+8 can be represented
291-
narrow.legalize(
292-
def!(a = load.I128(flags, ptr, Literal::constant(offset32, 0))),
293-
vec![
294-
def!(al = load.I64(flags, ptr, Literal::constant(offset32, 0))),
295-
def!(ah = load.I64(flags, ptr, Literal::constant(offset32, 8))),
296-
// `iconcat` expects the same byte order as stored in memory,
297-
// so no need to swap depending on endianness.
298-
def!(a = iconcat(al, ah)),
299-
],
300-
);
301-
302-
// FIXME generalize to any offset once offset+8 can be represented
303-
narrow.legalize(
304-
def!(store.I128(flags, a, ptr, Literal::constant(offset32, 0))),
305-
vec![
306-
// `isplit` gives the same byte order as stored in memory,
307-
// so no need to swap depending on endianness.
308-
def!((al, ah) = isplit(a)),
309-
def!(store.I64(flags, al, ptr, Literal::constant(offset32, 0))),
310-
def!(store.I64(flags, ah, ptr, Literal::constant(offset32, 8))),
311-
],
312-
);
289+
narrow.custom_legalize(load, "narrow_load");
290+
narrow.custom_legalize(store, "narrow_store");
313291

314292
// Widen instructions with one input operand.
315293
for &op in &[bnot, popcnt] {

cranelift-codegen/src/legalizer/mod.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,3 +507,63 @@ fn expand_stack_store(
507507
mflags.set_aligned();
508508
pos.func.dfg.replace(inst).store(mflags, val, addr, 0);
509509
}
510+
511+
/// Split a load into two parts before `iconcat`ing the result together.
512+
fn narrow_load(
513+
inst: ir::Inst,
514+
func: &mut ir::Function,
515+
_cfg: &mut ControlFlowGraph,
516+
_isa: &dyn TargetIsa,
517+
) {
518+
let mut pos = FuncCursor::new(func).at_inst(inst);
519+
pos.use_srcloc(inst);
520+
521+
let (ptr, offset, flags) = match pos.func.dfg[inst] {
522+
ir::InstructionData::Load {
523+
opcode: ir::Opcode::Load,
524+
arg,
525+
offset,
526+
flags,
527+
} => (arg, offset, flags),
528+
_ => panic!("Expected load: {}", pos.func.dfg.display_inst(inst, None)),
529+
};
530+
531+
let al = pos.ins().load(ir::types::I64, flags, ptr, offset);
532+
let ah = pos.ins().load(
533+
ir::types::I64,
534+
flags,
535+
ptr,
536+
offset.try_add_i64(8).expect("load offset overflow"),
537+
);
538+
pos.func.dfg.replace(inst).iconcat(al, ah);
539+
}
540+
541+
/// Split a store into two parts after `isplit`ing the value.
542+
fn narrow_store(
543+
inst: ir::Inst,
544+
func: &mut ir::Function,
545+
_cfg: &mut ControlFlowGraph,
546+
_isa: &dyn TargetIsa,
547+
) {
548+
let mut pos = FuncCursor::new(func).at_inst(inst);
549+
pos.use_srcloc(inst);
550+
551+
let (val, ptr, offset, flags) = match pos.func.dfg[inst] {
552+
ir::InstructionData::Store {
553+
opcode: ir::Opcode::Store,
554+
args,
555+
offset,
556+
flags,
557+
} => (args[0], args[1], offset, flags),
558+
_ => panic!("Expected store: {}", pos.func.dfg.display_inst(inst, None)),
559+
};
560+
561+
let (al, ah) = pos.func.dfg.replace(inst).isplit(val);
562+
pos.ins().store(flags, al, ptr, offset);
563+
pos.ins().store(
564+
flags,
565+
ah,
566+
ptr,
567+
offset.try_add_i64(8).expect("store offset overflow"),
568+
);
569+
}

filetests/isa/x86/i128.clif

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,19 @@ ebb0(v0: i128):
2828
}
2929

3030
function u0:2(i64, i128) fast {
31-
; check: ebb0(v0: i64 [%rdi], v2: i64 [%rsi], v3: i64 [%rdx], v4: i64 [%rbp]):
31+
; check: ebb0(v0: i64 [%rdi], v2: i64 [%rsi], v3: i64 [%rdx], v6: i64 [%rbp]):
3232
ebb0(v0: i64, v1: i128):
33-
; check: store v2, v0
34-
; check: store v3, v0+8
35-
store v1, v0
33+
; check: store v2, v0+8
34+
; check: store v3, v0+16
35+
store v1, v0+8
3636
return
3737
}
3838

3939
function u0:3(i64) -> i128 fast {
4040
ebb0(v0: i64):
41-
; check: v2 = load.i64 v0
42-
; check: v3 = load.i64 v0+8
43-
v1 = load.i128 v0
41+
; check: v2 = load.i64 v0+8
42+
; check: v3 = load.i64 v0+16
43+
v1 = load.i128 v0+8
4444
; check: return v2, v3, v5
4545
return v1
4646
}

0 commit comments

Comments
 (0)