YJIT: Implement opt_reverse insn (#12175)
This commit is contained in:
parent
33f15ce80d
commit
8f9b9aecd0
Notes:
git
2024-11-26 21:49:46 +00:00
Merged-By: maximecb <maximecb@ruby-lang.org>
@ -5309,3 +5309,33 @@ assert_equal '[true, false]', <<~'RUBY'
|
|||||||
test("c"),
|
test("c"),
|
||||||
]
|
]
|
||||||
RUBY
|
RUBY
|
||||||
|
|
||||||
|
# YARV: swap and opt_reverse
|
||||||
|
assert_equal '["x", "Y", "c", "A", "t", "A", "b", "C", "d"]', <<~'RUBY'
|
||||||
|
class Swap
|
||||||
|
def initialize(s)
|
||||||
|
@a, @b, @c, @d = s.split("")
|
||||||
|
end
|
||||||
|
|
||||||
|
def swap
|
||||||
|
a, b = @a, @b
|
||||||
|
b = b.upcase
|
||||||
|
@a, @b = a, b
|
||||||
|
end
|
||||||
|
|
||||||
|
def reverse_odd
|
||||||
|
a, b, c = @a, @b, @c
|
||||||
|
b = b.upcase
|
||||||
|
@a, @b, @c = a, b, c
|
||||||
|
end
|
||||||
|
|
||||||
|
def reverse_even
|
||||||
|
a, b, c, d = @a, @b, @c, @d
|
||||||
|
a = a.upcase
|
||||||
|
c = c.upcase
|
||||||
|
@a, @b, @c, @d = a, b, c, d
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Swap.new("xy").swap + Swap.new("cat").reverse_odd + Swap.new("abcd").reverse_even
|
||||||
|
RUBY
|
||||||
|
@ -1489,6 +1489,18 @@ fn gen_dupn(
|
|||||||
Some(KeepCompiling)
|
Some(KeepCompiling)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reverse top X stack entries
|
||||||
|
fn gen_opt_reverse(
|
||||||
|
jit: &mut JITState,
|
||||||
|
asm: &mut Assembler,
|
||||||
|
) -> Option<CodegenStatus> {
|
||||||
|
let count = jit.get_arg(0).as_i32();
|
||||||
|
for n in 0..(count/2) {
|
||||||
|
stack_swap(asm, n, count - 1 - n);
|
||||||
|
}
|
||||||
|
Some(KeepCompiling)
|
||||||
|
}
|
||||||
|
|
||||||
// Swap top 2 stack entries
|
// Swap top 2 stack entries
|
||||||
fn gen_swap(
|
fn gen_swap(
|
||||||
_jit: &mut JITState,
|
_jit: &mut JITState,
|
||||||
@ -10517,6 +10529,7 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
|
|||||||
YARVINSN_dup => Some(gen_dup),
|
YARVINSN_dup => Some(gen_dup),
|
||||||
YARVINSN_dupn => Some(gen_dupn),
|
YARVINSN_dupn => Some(gen_dupn),
|
||||||
YARVINSN_swap => Some(gen_swap),
|
YARVINSN_swap => Some(gen_swap),
|
||||||
|
YARVINSN_opt_reverse => Some(gen_opt_reverse),
|
||||||
YARVINSN_putnil => Some(gen_putnil),
|
YARVINSN_putnil => Some(gen_putnil),
|
||||||
YARVINSN_putobject => Some(gen_putobject),
|
YARVINSN_putobject => Some(gen_putobject),
|
||||||
YARVINSN_putobject_INT2FIX_0_ => Some(gen_putobject_int2fix),
|
YARVINSN_putobject_INT2FIX_0_ => Some(gen_putobject_int2fix),
|
||||||
@ -11093,6 +11106,41 @@ mod tests {
|
|||||||
assert!(cb.get_write_pos() > 0); // Write some movs
|
assert!(cb.get_write_pos() > 0); // Write some movs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gen_opt_reverse() {
|
||||||
|
let (_context, mut asm, mut cb, mut ocb) = setup_codegen();
|
||||||
|
let mut jit = dummy_jit_state(&mut cb, &mut ocb);
|
||||||
|
|
||||||
|
// Odd number of elements
|
||||||
|
asm.stack_push(Type::Fixnum);
|
||||||
|
asm.stack_push(Type::Flonum);
|
||||||
|
asm.stack_push(Type::CString);
|
||||||
|
|
||||||
|
let mut value_array: [u64; 2] = [0, 3];
|
||||||
|
let pc: *mut VALUE = &mut value_array as *mut u64 as *mut VALUE;
|
||||||
|
jit.pc = pc;
|
||||||
|
|
||||||
|
let mut status = gen_opt_reverse(&mut jit, &mut asm);
|
||||||
|
|
||||||
|
assert_eq!(status, Some(KeepCompiling));
|
||||||
|
|
||||||
|
assert_eq!(Type::CString, asm.ctx.get_opnd_type(StackOpnd(2)));
|
||||||
|
assert_eq!(Type::Flonum, asm.ctx.get_opnd_type(StackOpnd(1)));
|
||||||
|
assert_eq!(Type::Fixnum, asm.ctx.get_opnd_type(StackOpnd(0)));
|
||||||
|
|
||||||
|
// Try again with an even number of elements.
|
||||||
|
asm.stack_push(Type::Nil);
|
||||||
|
value_array[1] = 4;
|
||||||
|
status = gen_opt_reverse(&mut jit, &mut asm);
|
||||||
|
|
||||||
|
assert_eq!(status, Some(KeepCompiling));
|
||||||
|
|
||||||
|
assert_eq!(Type::Nil, asm.ctx.get_opnd_type(StackOpnd(3)));
|
||||||
|
assert_eq!(Type::Fixnum, asm.ctx.get_opnd_type(StackOpnd(2)));
|
||||||
|
assert_eq!(Type::Flonum, asm.ctx.get_opnd_type(StackOpnd(1)));
|
||||||
|
assert_eq!(Type::CString, asm.ctx.get_opnd_type(StackOpnd(0)));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gen_swap() {
|
fn test_gen_swap() {
|
||||||
let (_context, mut asm, mut cb, mut ocb) = setup_codegen();
|
let (_context, mut asm, mut cb, mut ocb) = setup_codegen();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user