Skip to content

Commit 3f1304a

Browse files
committed
Implement int extension
1 parent fb95096 commit 3f1304a

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

src/builder.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1219,7 +1219,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
12191219
// TODO(antoyo): nothing to do as it is only for LLVM?
12201220
return value;
12211221
}
1222-
self.context.new_cast(self.location, value, dest_ty)
1222+
1223+
self.extend_int(value, dest_ty, true)
12231224
}
12241225

12251226
fn fptoui(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
@@ -1700,9 +1701,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
17001701
call
17011702
}
17021703

1703-
fn zext(&mut self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> {
1704-
// FIXME(antoyo): this does not zero-extend.
1705-
self.gcc_int_cast(value, dest_typ)
1704+
fn zext(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
1705+
self.extend_int(value, dest_ty, false)
17061706
}
17071707

17081708
fn cx(&self) -> &CodegenCx<'gcc, 'tcx> {

src/context.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ use rustc_data_structures::base_n::ToBaseN;
1010
use rustc_data_structures::base_n::ALPHANUMERIC_ONLY;
1111
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1212
use rustc_middle::mir::mono::CodegenUnit;
13-
use rustc_middle::span_bug;
1413
use rustc_middle::ty::layout::{
1514
FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError,
1615
LayoutOfHelpers, TyAndLayout,
1716
};
1817
use rustc_middle::ty::{self, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt};
18+
use rustc_middle::{bug, span_bug};
1919
use rustc_session::Session;
2020
use rustc_span::{source_map::respan, Span};
2121
use rustc_target::abi::{
@@ -360,6 +360,31 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
360360
function
361361
}
362362

363+
pub fn get_matching_int_type(&self, typ: Type<'gcc>, signed: bool) -> Type<'gcc> {
364+
let size = if typ.is_compatible_with(self.bool_type) {
365+
// For booleans, return an 8-bit integer instead.
366+
1
367+
} else {
368+
typ.get_size()
369+
};
370+
371+
match (size, signed) {
372+
(1, false) => self.u8_type,
373+
(2, false) => self.u16_type,
374+
(4, false) => self.u32_type,
375+
(8, false) => self.u64_type,
376+
(16, false) => self.u128_type,
377+
(1, true) => self.i8_type,
378+
(2, true) => self.i16_type,
379+
(4, true) => self.i32_type,
380+
(8, true) => self.i64_type,
381+
(16, true) => self.i128_type,
382+
_ => {
383+
bug!("attempt to get bad int type {}{}", if signed { 'i' } else { 'u' }, size * 8);
384+
}
385+
}
386+
}
387+
363388
pub fn is_native_int_type(&self, typ: Type<'gcc>) -> bool {
364389
let types = [
365390
self.u8_type,

src/int.rs

+16
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use gccjit::{BinaryOp, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp};
66
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
77
use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeMethods, BuilderMethods, OverflowOp};
8+
use rustc_middle::bug;
89
use rustc_middle::ty::{ParamEnv, Ty};
910
use rustc_target::abi::{
1011
call::{ArgAbi, ArgAttributes, Conv, FnAbi, PassMode},
@@ -866,6 +867,21 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
866867
self.bitwise_operation(BinaryOp::BitwiseOr, a, b, loc)
867868
}
868869

870+
pub fn extend_int(
871+
&self,
872+
value: RValue<'gcc>,
873+
dest_ty: Type<'gcc>,
874+
signed: bool,
875+
) -> RValue<'gcc> {
876+
let src_ty = value.get_type();
877+
if !self.is_int_type_or_bool(src_ty) || !self.is_int_type_or_bool(dest_ty) {
878+
bug!("got extend_int for non-int type {:?} -> {:?}", src_ty, dest_ty);
879+
}
880+
881+
let intermediate_ty = self.get_matching_int_type(src_ty, signed);
882+
self.gcc_int_cast(self.gcc_int_cast(value, intermediate_ty), dest_ty)
883+
}
884+
869885
// TODO(antoyo): can we use https://github.com/rust-lang/compiler-builtins/blob/master/src/int/mod.rs#L379 instead?
870886
pub fn gcc_int_cast(&self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> {
871887
let value_type = value.get_type();

0 commit comments

Comments
 (0)