diff --git a/cranelift/codegen/src/isa/aarch64/lower_inst.rs b/cranelift/codegen/src/isa/aarch64/lower_inst.rs index 54fbd5671a..743a9a81ea 100644 --- a/cranelift/codegen/src/isa/aarch64/lower_inst.rs +++ b/cranelift/codegen/src/isa/aarch64/lower_inst.rs @@ -50,6 +50,15 @@ pub(crate) fn lower_insn_to_regs>( match op { Opcode::Iconst | Opcode::Bconst | Opcode::Null => { let value = ctx.get_constant(insn).unwrap(); + // Sign extend constant if necessary + let value = match ty.unwrap() { + I8 => (((value as i64) << 8) >> 8) as u64, + I16 => (((value as i64) << 16) >> 16) as u64, + I32 => (((value as i64) << 32) >> 32) as u64, + I64 | R64 => value, + ty if ty.is_bool() => value, + ty => unreachable!("Unknown type for const: {}", ty), + }; let rd = get_output_reg(ctx, outputs[0]); lower_constant_u64(ctx, rd, value); } diff --git a/cranelift/codegen/src/isa/x64/lower.rs b/cranelift/codegen/src/isa/x64/lower.rs index caa8f6fbb1..acd6ee1d1c 100644 --- a/cranelift/codegen/src/isa/x64/lower.rs +++ b/cranelift/codegen/src/isa/x64/lower.rs @@ -179,12 +179,13 @@ fn extend_input_to_reg(ctx: Ctx, spec: InsnInput, ext_spec: ExtSpec) -> Reg { let ext_mode = match (input_size, requested_size) { (a, b) if a == b => return input_to_reg(ctx, spec), - (a, 32) if a == 1 || a == 8 => ExtMode::BL, + (1, 8) => return input_to_reg(ctx, spec), + (a, 16) | (a, 32) if a == 1 || a == 8 => ExtMode::BL, (a, 64) if a == 1 || a == 8 => ExtMode::BQ, (16, 32) => ExtMode::WL, (16, 64) => ExtMode::WQ, (32, 64) => ExtMode::LQ, - _ => unreachable!(), + _ => unreachable!("extend {} -> {}", input_size, requested_size), }; let src = input_to_reg_mem(ctx, spec); @@ -1108,7 +1109,7 @@ fn lower_insn_to_regs>( let dst = output_to_reg(ctx, outputs[0]); let ext_mode = match (src_ty.bits(), dst_ty.bits()) { - (1, 32) | (8, 32) => Some(ExtMode::BL), + (1, 8) | (1, 16) | (1, 32) | (8, 16) | (8, 32) => Some(ExtMode::BL), (1, 64) | (8, 64) => Some(ExtMode::BQ), (16, 32) => Some(ExtMode::WL), (16, 64) => Some(ExtMode::WQ),