Added self argument for Codegen CommonMethod trait methods
This commit is contained in:
parent
d325844804
commit
83e07f9fe9
11 changed files with 119 additions and 118 deletions
|
@ -529,8 +529,8 @@ impl BuilderMethods<'a, 'll, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let llty = CodegenCx::val_ty(load);
|
let llty = CodegenCx::val_ty(load);
|
||||||
let v = [
|
let v = [
|
||||||
CodegenCx::c_uint_big(llty, range.start),
|
self.cx.c_uint_big(llty, range.start),
|
||||||
CodegenCx::c_uint_big(llty, range.end)
|
self.cx.c_uint_big(llty, range.end)
|
||||||
];
|
];
|
||||||
|
|
||||||
llvm::LLVMSetMetadata(load, llvm::MD_range as c_uint,
|
llvm::LLVMSetMetadata(load, llvm::MD_range as c_uint,
|
||||||
|
@ -863,7 +863,7 @@ impl BuilderMethods<'a, 'll, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
let undef = llvm::LLVMGetUndef(type_::Type::vector(elt_ty, num_elts as u64));
|
let undef = llvm::LLVMGetUndef(type_::Type::vector(elt_ty, num_elts as u64));
|
||||||
let vec = self.insert_element(undef, elt, CodegenCx::c_i32(self.cx, 0));
|
let vec = self.insert_element(undef, elt, CodegenCx::c_i32(self.cx, 0));
|
||||||
let vec_i32_ty = type_::Type::vector(type_::Type::i32(self.cx), num_elts as u64);
|
let vec_i32_ty = type_::Type::vector(type_::Type::i32(self.cx), num_elts as u64);
|
||||||
self.shuffle_vector(vec, undef, CodegenCx::c_null(vec_i32_ty))
|
self.shuffle_vector(vec, undef, self.cx.c_null(vec_i32_ty))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -208,31 +208,31 @@ impl<'ll, 'tcx : 'll> CommonMethods for CodegenCx<'ll, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LLVM constant constructors.
|
// LLVM constant constructors.
|
||||||
fn c_null(t: &'ll Type) -> &'ll Value {
|
fn c_null(&self, t: &'ll Type) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMConstNull(t)
|
llvm::LLVMConstNull(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn c_undef(t: &'ll Type) -> &'ll Value {
|
fn c_undef(&self, t: &'ll Type) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMGetUndef(t)
|
llvm::LLVMGetUndef(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn c_int(t: &'ll Type, i: i64) -> &'ll Value {
|
fn c_int(&self, t: &'ll Type, i: i64) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMConstInt(t, i as u64, True)
|
llvm::LLVMConstInt(t, i as u64, True)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn c_uint(t: &'ll Type, i: u64) -> &'ll Value {
|
fn c_uint(&self, t: &'ll Type, i: u64) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMConstInt(t, i, False)
|
llvm::LLVMConstInt(t, i, False)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn c_uint_big(t: &'ll Type, u: u128) -> &'ll Value {
|
fn c_uint_big(&self, t: &'ll Type, u: u128) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
let words = [u as u64, (u >> 64) as u64];
|
let words = [u as u64, (u >> 64) as u64];
|
||||||
llvm::LLVMConstIntOfArbitraryPrecision(t, 2, words.as_ptr())
|
llvm::LLVMConstIntOfArbitraryPrecision(t, 2, words.as_ptr())
|
||||||
|
@ -240,19 +240,19 @@ impl<'ll, 'tcx : 'll> CommonMethods for CodegenCx<'ll, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn c_bool(&self, val: bool) -> &'ll Value {
|
fn c_bool(&self, val: bool) -> &'ll Value {
|
||||||
Self::c_uint(Type::i1(&self), val as u64)
|
&self.c_uint(Type::i1(&self), val as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn c_i32(&self, i: i32) -> &'ll Value {
|
fn c_i32(&self, i: i32) -> &'ll Value {
|
||||||
Self::c_int(Type::i32(&self), i as i64)
|
&self.c_int(Type::i32(&self), i as i64)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn c_u32(&self, i: u32) -> &'ll Value {
|
fn c_u32(&self, i: u32) -> &'ll Value {
|
||||||
Self::c_uint(Type::i32(&self), i as u64)
|
&self.c_uint(Type::i32(&self), i as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn c_u64(&self, i: u64) -> &'ll Value {
|
fn c_u64(&self, i: u64) -> &'ll Value {
|
||||||
Self::c_uint(Type::i64(&self), i)
|
&self.c_uint(Type::i64(&self), i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn c_usize(&self, i: u64) -> &'ll Value {
|
fn c_usize(&self, i: u64) -> &'ll Value {
|
||||||
|
@ -262,11 +262,11 @@ impl<'ll, 'tcx : 'll> CommonMethods for CodegenCx<'ll, 'tcx> {
|
||||||
assert!(i < (1<<bit_size));
|
assert!(i < (1<<bit_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::c_uint(&self.isize_ty, i)
|
&self.c_uint(&self.isize_ty, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn c_u8(&self, i: u8) -> &'ll Value {
|
fn c_u8(&self, i: u8) -> &'ll Value {
|
||||||
Self::c_uint(Type::i8(&self), i as u64)
|
&self.c_uint(Type::i8(&self), i as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -489,9 +489,9 @@ pub fn shift_mask_val(
|
||||||
// i8/u8 can shift by at most 7, i16/u16 by at most 15, etc.
|
// i8/u8 can shift by at most 7, i16/u16 by at most 15, etc.
|
||||||
let val = llty.int_width() - 1;
|
let val = llty.int_width() - 1;
|
||||||
if invert {
|
if invert {
|
||||||
CodegenCx::c_int(mask_llty, !val as i64)
|
bx.cx.c_int(mask_llty, !val as i64)
|
||||||
} else {
|
} else {
|
||||||
CodegenCx::c_uint(mask_llty, val)
|
bx.cx.c_uint(mask_llty, val)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TypeKind::Vector => {
|
TypeKind::Vector => {
|
||||||
|
|
|
@ -15,11 +15,11 @@ pub trait CommonMethods : Backend {
|
||||||
fn val_ty(v: Self::Value) -> Self::Type;
|
fn val_ty(v: Self::Value) -> Self::Type;
|
||||||
|
|
||||||
// Constant constructors
|
// Constant constructors
|
||||||
fn c_null(t: Self::Type) -> Self::Value;
|
fn c_null(&self, t: Self::Type) -> Self::Value;
|
||||||
fn c_undef(t: Self::Type) -> Self::Value;
|
fn c_undef(&self, t: Self::Type) -> Self::Value;
|
||||||
fn c_int(t: Self::Type, i: i64) -> Self::Value;
|
fn c_int(&self, t: Self::Type, i: i64) -> Self::Value;
|
||||||
fn c_uint(t: Self::Type, i: u64) -> Self::Value;
|
fn c_uint(&self, t: Self::Type, i: u64) -> Self::Value;
|
||||||
fn c_uint_big(t: Self::Type, u: u128) -> Self::Value;
|
fn c_uint_big(&self, t: Self::Type, u: u128) -> Self::Value;
|
||||||
fn c_bool(&self, val: bool) -> Self::Value;
|
fn c_bool(&self, val: bool) -> Self::Value;
|
||||||
fn c_i32(&self, i: i32) -> Self::Value;
|
fn c_i32(&self, i: i32) -> Self::Value;
|
||||||
fn c_u32(&self, i: u32) -> Self::Value;
|
fn c_u32(&self, i: u32) -> Self::Value;
|
||||||
|
|
|
@ -127,11 +127,11 @@ pub fn codegen_intrinsic_call(
|
||||||
},
|
},
|
||||||
"likely" => {
|
"likely" => {
|
||||||
let expect = cx.get_intrinsic(&("llvm.expect.i1"));
|
let expect = cx.get_intrinsic(&("llvm.expect.i1"));
|
||||||
bx.call(expect, &[args[0].immediate(), CodegenCx::c_bool(cx, true)], None)
|
bx.call(expect, &[args[0].immediate(), bx.cx().c_bool(true)], None)
|
||||||
}
|
}
|
||||||
"unlikely" => {
|
"unlikely" => {
|
||||||
let expect = cx.get_intrinsic(&("llvm.expect.i1"));
|
let expect = cx.get_intrinsic(&("llvm.expect.i1"));
|
||||||
bx.call(expect, &[args[0].immediate(), CodegenCx::c_bool(cx, false)], None)
|
bx.call(expect, &[args[0].immediate(), bx.cx().c_bool(false)], None)
|
||||||
}
|
}
|
||||||
"try" => {
|
"try" => {
|
||||||
try_intrinsic(bx, cx,
|
try_intrinsic(bx, cx,
|
||||||
|
@ -147,7 +147,7 @@ pub fn codegen_intrinsic_call(
|
||||||
}
|
}
|
||||||
"size_of" => {
|
"size_of" => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = substs.type_at(0);
|
||||||
CodegenCx::c_usize(cx, cx.size_of(tp_ty).bytes())
|
cx.c_usize(cx.size_of(tp_ty).bytes())
|
||||||
}
|
}
|
||||||
"size_of_val" => {
|
"size_of_val" => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = substs.type_at(0);
|
||||||
|
@ -156,12 +156,12 @@ pub fn codegen_intrinsic_call(
|
||||||
glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
|
glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
|
||||||
llsize
|
llsize
|
||||||
} else {
|
} else {
|
||||||
CodegenCx::c_usize(cx, cx.size_of(tp_ty).bytes())
|
cx.c_usize(cx.size_of(tp_ty).bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"min_align_of" => {
|
"min_align_of" => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = substs.type_at(0);
|
||||||
CodegenCx::c_usize(cx, cx.align_of(tp_ty).abi())
|
cx.c_usize(cx.align_of(tp_ty).abi())
|
||||||
}
|
}
|
||||||
"min_align_of_val" => {
|
"min_align_of_val" => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = substs.type_at(0);
|
||||||
|
@ -170,20 +170,20 @@ pub fn codegen_intrinsic_call(
|
||||||
glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
|
glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
|
||||||
llalign
|
llalign
|
||||||
} else {
|
} else {
|
||||||
CodegenCx::c_usize(cx, cx.align_of(tp_ty).abi())
|
cx.c_usize(cx.align_of(tp_ty).abi())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"pref_align_of" => {
|
"pref_align_of" => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = substs.type_at(0);
|
||||||
CodegenCx::c_usize(cx, cx.align_of(tp_ty).pref())
|
cx.c_usize(cx.align_of(tp_ty).pref())
|
||||||
}
|
}
|
||||||
"type_name" => {
|
"type_name" => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = substs.type_at(0);
|
||||||
let ty_name = Symbol::intern(&tp_ty.to_string()).as_str();
|
let ty_name = Symbol::intern(&tp_ty.to_string()).as_str();
|
||||||
CodegenCx::c_str_slice(cx, ty_name)
|
cx.c_str_slice(ty_name)
|
||||||
}
|
}
|
||||||
"type_id" => {
|
"type_id" => {
|
||||||
CodegenCx::c_u64(cx, cx.tcx.type_id_hash(substs.type_at(0)))
|
cx.c_u64(cx.tcx.type_id_hash(substs.type_at(0)))
|
||||||
}
|
}
|
||||||
"init" => {
|
"init" => {
|
||||||
let ty = substs.type_at(0);
|
let ty = substs.type_at(0);
|
||||||
|
@ -197,8 +197,8 @@ pub fn codegen_intrinsic_call(
|
||||||
false,
|
false,
|
||||||
ty,
|
ty,
|
||||||
llresult,
|
llresult,
|
||||||
CodegenCx::c_u8(cx, 0),
|
cx.c_u8(0),
|
||||||
CodegenCx::c_usize(cx, 1)
|
cx.c_usize(1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -210,7 +210,7 @@ pub fn codegen_intrinsic_call(
|
||||||
"needs_drop" => {
|
"needs_drop" => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = substs.type_at(0);
|
||||||
|
|
||||||
CodegenCx::c_bool(cx, bx.cx().type_needs_drop(tp_ty))
|
cx.c_bool(bx.cx().type_needs_drop(tp_ty))
|
||||||
}
|
}
|
||||||
"offset" => {
|
"offset" => {
|
||||||
let ptr = args[0].immediate();
|
let ptr = args[0].immediate();
|
||||||
|
@ -287,9 +287,9 @@ pub fn codegen_intrinsic_call(
|
||||||
};
|
};
|
||||||
bx.call(expect, &[
|
bx.call(expect, &[
|
||||||
args[0].immediate(),
|
args[0].immediate(),
|
||||||
CodegenCx::c_i32(cx, rw),
|
cx.c_i32(rw),
|
||||||
args[1].immediate(),
|
args[1].immediate(),
|
||||||
CodegenCx::c_i32(cx, cache_type)
|
cx.c_i32(cache_type)
|
||||||
], None)
|
], None)
|
||||||
},
|
},
|
||||||
"ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" |
|
"ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" |
|
||||||
|
@ -302,12 +302,12 @@ pub fn codegen_intrinsic_call(
|
||||||
Some((width, signed)) =>
|
Some((width, signed)) =>
|
||||||
match name {
|
match name {
|
||||||
"ctlz" | "cttz" => {
|
"ctlz" | "cttz" => {
|
||||||
let y = CodegenCx::c_bool(bx.cx(), false);
|
let y = cx.c_bool(false);
|
||||||
let llfn = cx.get_intrinsic(&format!("llvm.{}.i{}", name, width));
|
let llfn = cx.get_intrinsic(&format!("llvm.{}.i{}", name, width));
|
||||||
bx.call(llfn, &[args[0].immediate(), y], None)
|
bx.call(llfn, &[args[0].immediate(), y], None)
|
||||||
}
|
}
|
||||||
"ctlz_nonzero" | "cttz_nonzero" => {
|
"ctlz_nonzero" | "cttz_nonzero" => {
|
||||||
let y = CodegenCx::c_bool(bx.cx(), true);
|
let y = cx.c_bool(true);
|
||||||
let llvm_name = &format!("llvm.{}.i{}", &name[..4], width);
|
let llvm_name = &format!("llvm.{}.i{}", &name[..4], width);
|
||||||
let llfn = cx.get_intrinsic(llvm_name);
|
let llfn = cx.get_intrinsic(llvm_name);
|
||||||
bx.call(llfn, &[args[0].immediate(), y], None)
|
bx.call(llfn, &[args[0].immediate(), y], None)
|
||||||
|
@ -388,7 +388,7 @@ pub fn codegen_intrinsic_call(
|
||||||
} else {
|
} else {
|
||||||
// rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
|
// rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
|
||||||
// rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
|
// rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
|
||||||
let width = CodegenCx::c_uint(Type::ix(cx, width), width);
|
let width = cx.c_uint(Type::ix(cx, width), width);
|
||||||
let shift = bx.urem(raw_shift, width);
|
let shift = bx.urem(raw_shift, width);
|
||||||
let inv_shift = bx.urem(bx.sub(width, raw_shift), width);
|
let inv_shift = bx.urem(bx.sub(width, raw_shift), width);
|
||||||
let shift1 = bx.shl(val, if is_left { shift } else { inv_shift });
|
let shift1 = bx.shl(val, if is_left { shift } else { inv_shift });
|
||||||
|
@ -725,7 +725,7 @@ fn copy_intrinsic(
|
||||||
) -> &'ll Value {
|
) -> &'ll Value {
|
||||||
let cx = bx.cx();
|
let cx = bx.cx();
|
||||||
let (size, align) = cx.size_and_align_of(ty);
|
let (size, align) = cx.size_and_align_of(ty);
|
||||||
let size = CodegenCx::c_usize(cx, size.bytes());
|
let size = cx.c_usize(size.bytes());
|
||||||
let align = align.abi();
|
let align = align.abi();
|
||||||
let dst_ptr = bx.pointercast(dst, Type::i8p(cx));
|
let dst_ptr = bx.pointercast(dst, Type::i8p(cx));
|
||||||
let src_ptr = bx.pointercast(src, Type::i8p(cx));
|
let src_ptr = bx.pointercast(src, Type::i8p(cx));
|
||||||
|
@ -746,8 +746,8 @@ fn memset_intrinsic(
|
||||||
) -> &'ll Value {
|
) -> &'ll Value {
|
||||||
let cx = bx.cx();
|
let cx = bx.cx();
|
||||||
let (size, align) = cx.size_and_align_of(ty);
|
let (size, align) = cx.size_and_align_of(ty);
|
||||||
let size = CodegenCx::c_usize(cx, size.bytes());
|
let size = cx.c_usize(size.bytes());
|
||||||
let align = CodegenCx::c_i32(cx, align.abi() as i32);
|
let align = cx.c_i32(align.abi() as i32);
|
||||||
let dst = bx.pointercast(dst, Type::i8p(cx));
|
let dst = bx.pointercast(dst, Type::i8p(cx));
|
||||||
call_memset(bx, dst, val, bx.mul(size, count), align, volatile)
|
call_memset(bx, dst, val, bx.mul(size, count), align, volatile)
|
||||||
}
|
}
|
||||||
|
@ -763,7 +763,7 @@ fn try_intrinsic(
|
||||||
if bx.sess().no_landing_pads() {
|
if bx.sess().no_landing_pads() {
|
||||||
bx.call(func, &[data], None);
|
bx.call(func, &[data], None);
|
||||||
let ptr_align = bx.tcx().data_layout.pointer_align;
|
let ptr_align = bx.tcx().data_layout.pointer_align;
|
||||||
bx.store(CodegenCx::c_null(Type::i8p(&bx.cx())), dest, ptr_align);
|
bx.store(bx.cx().c_null(Type::i8p(&bx.cx())), dest, ptr_align);
|
||||||
} else if wants_msvc_seh(bx.sess()) {
|
} else if wants_msvc_seh(bx.sess()) {
|
||||||
codegen_msvc_try(bx, cx, func, data, local_ptr, dest);
|
codegen_msvc_try(bx, cx, func, data, local_ptr, dest);
|
||||||
} else {
|
} else {
|
||||||
|
@ -844,7 +844,7 @@ fn codegen_msvc_try(
|
||||||
let slot = bx.alloca(i64p, "slot", ptr_align);
|
let slot = bx.alloca(i64p, "slot", ptr_align);
|
||||||
bx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(), None);
|
bx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(), None);
|
||||||
|
|
||||||
normal.ret(CodegenCx::c_i32(cx, 0));
|
normal.ret(cx.c_i32(0));
|
||||||
|
|
||||||
let cs = catchswitch.catch_switch(None, None, 1);
|
let cs = catchswitch.catch_switch(None, None, 1);
|
||||||
catchswitch.add_handler(cs, catchpad.llbb());
|
catchswitch.add_handler(cs, catchpad.llbb());
|
||||||
|
@ -854,19 +854,19 @@ fn codegen_msvc_try(
|
||||||
Some(did) => ::consts::get_static(cx, did),
|
Some(did) => ::consts::get_static(cx, did),
|
||||||
None => bug!("msvc_try_filter not defined"),
|
None => bug!("msvc_try_filter not defined"),
|
||||||
};
|
};
|
||||||
let tok = catchpad.catch_pad(cs, &[tydesc, CodegenCx::c_i32(cx, 0), slot]);
|
let tok = catchpad.catch_pad(cs, &[tydesc, cx.c_i32(0), slot]);
|
||||||
let addr = catchpad.load(slot, ptr_align);
|
let addr = catchpad.load(slot, ptr_align);
|
||||||
|
|
||||||
let i64_align = bx.tcx().data_layout.i64_align;
|
let i64_align = bx.tcx().data_layout.i64_align;
|
||||||
let arg1 = catchpad.load(addr, i64_align);
|
let arg1 = catchpad.load(addr, i64_align);
|
||||||
let val1 = CodegenCx::c_i32(cx, 1);
|
let val1 = cx.c_i32(1);
|
||||||
let arg2 = catchpad.load(catchpad.inbounds_gep(addr, &[val1]), i64_align);
|
let arg2 = catchpad.load(catchpad.inbounds_gep(addr, &[val1]), i64_align);
|
||||||
let local_ptr = catchpad.bitcast(local_ptr, i64p);
|
let local_ptr = catchpad.bitcast(local_ptr, i64p);
|
||||||
catchpad.store(arg1, local_ptr, i64_align);
|
catchpad.store(arg1, local_ptr, i64_align);
|
||||||
catchpad.store(arg2, catchpad.inbounds_gep(local_ptr, &[val1]), i64_align);
|
catchpad.store(arg2, catchpad.inbounds_gep(local_ptr, &[val1]), i64_align);
|
||||||
catchpad.catch_ret(tok, caught.llbb());
|
catchpad.catch_ret(tok, caught.llbb());
|
||||||
|
|
||||||
caught.ret(CodegenCx::c_i32(cx, 1));
|
caught.ret(cx.c_i32(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Note that no invoke is used here because by definition this function
|
// Note that no invoke is used here because by definition this function
|
||||||
|
@ -922,7 +922,7 @@ fn codegen_gnu_try(
|
||||||
let data = llvm::get_param(bx.llfn(), 1);
|
let data = llvm::get_param(bx.llfn(), 1);
|
||||||
let local_ptr = llvm::get_param(bx.llfn(), 2);
|
let local_ptr = llvm::get_param(bx.llfn(), 2);
|
||||||
bx.invoke(func, &[data], then.llbb(), catch.llbb(), None);
|
bx.invoke(func, &[data], then.llbb(), catch.llbb(), None);
|
||||||
then.ret(CodegenCx::c_i32(cx, 0));
|
then.ret(cx.c_i32(0));
|
||||||
|
|
||||||
// Type indicator for the exception being thrown.
|
// Type indicator for the exception being thrown.
|
||||||
//
|
//
|
||||||
|
@ -932,11 +932,11 @@ fn codegen_gnu_try(
|
||||||
// rust_try ignores the selector.
|
// rust_try ignores the selector.
|
||||||
let lpad_ty = Type::struct_(cx, &[Type::i8p(cx), Type::i32(cx)], false);
|
let lpad_ty = Type::struct_(cx, &[Type::i8p(cx), Type::i32(cx)], false);
|
||||||
let vals = catch.landing_pad(lpad_ty, bx.cx().eh_personality(), 1);
|
let vals = catch.landing_pad(lpad_ty, bx.cx().eh_personality(), 1);
|
||||||
catch.add_clause(vals, CodegenCx::c_null(Type::i8p(cx)));
|
catch.add_clause(vals, bx.cx().c_null(Type::i8p(cx)));
|
||||||
let ptr = catch.extract_value(vals, 0);
|
let ptr = catch.extract_value(vals, 0);
|
||||||
let ptr_align = bx.tcx().data_layout.pointer_align;
|
let ptr_align = bx.tcx().data_layout.pointer_align;
|
||||||
catch.store(ptr, catch.bitcast(local_ptr, Type::i8p(cx).ptr_to()), ptr_align);
|
catch.store(ptr, catch.bitcast(local_ptr, Type::i8p(cx).ptr_to()), ptr_align);
|
||||||
catch.ret(CodegenCx::c_i32(cx, 1));
|
catch.ret(cx.c_i32(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Note that no invoke is used here because by definition this function
|
// Note that no invoke is used here because by definition this function
|
||||||
|
@ -1125,13 +1125,13 @@ fn generic_simd_intrinsic(
|
||||||
arg_idx, total_len);
|
arg_idx, total_len);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
Some(idx) => Some(CodegenCx::c_i32(bx.cx(), idx as i32)),
|
Some(idx) => Some(bx.cx().c_i32(idx as i32)),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let indices = match indices {
|
let indices = match indices {
|
||||||
Some(i) => i,
|
Some(i) => i,
|
||||||
None => return Ok(CodegenCx::c_null(llret_ty))
|
None => return Ok(bx.cx().c_null(llret_ty))
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(bx.shuffle_vector(args[0].immediate(),
|
return Ok(bx.shuffle_vector(args[0].immediate(),
|
||||||
|
@ -1387,7 +1387,7 @@ fn generic_simd_intrinsic(
|
||||||
|
|
||||||
// Alignment of T, must be a constant integer value:
|
// Alignment of T, must be a constant integer value:
|
||||||
let alignment_ty = Type::i32(bx.cx());
|
let alignment_ty = Type::i32(bx.cx());
|
||||||
let alignment = CodegenCx::c_i32(bx.cx(), bx.cx().align_of(in_elem).abi() as i32);
|
let alignment = bx.cx().c_i32(bx.cx().align_of(in_elem).abi() as i32);
|
||||||
|
|
||||||
// Truncate the mask vector to a vector of i1s:
|
// Truncate the mask vector to a vector of i1s:
|
||||||
let (mask, mask_ty) = {
|
let (mask, mask_ty) = {
|
||||||
|
@ -1487,7 +1487,7 @@ fn generic_simd_intrinsic(
|
||||||
|
|
||||||
// Alignment of T, must be a constant integer value:
|
// Alignment of T, must be a constant integer value:
|
||||||
let alignment_ty = Type::i32(bx.cx());
|
let alignment_ty = Type::i32(bx.cx());
|
||||||
let alignment = CodegenCx::c_i32(bx.cx(), bx.cx().align_of(in_elem).abi() as i32);
|
let alignment = bx.cx().c_i32(bx.cx().align_of(in_elem).abi() as i32);
|
||||||
|
|
||||||
// Truncate the mask vector to a vector of i1s:
|
// Truncate the mask vector to a vector of i1s:
|
||||||
let (mask, mask_ty) = {
|
let (mask, mask_ty) = {
|
||||||
|
@ -1565,8 +1565,8 @@ fn generic_simd_intrinsic(
|
||||||
} else {
|
} else {
|
||||||
// unordered arithmetic reductions do not:
|
// unordered arithmetic reductions do not:
|
||||||
match f.bit_width() {
|
match f.bit_width() {
|
||||||
32 => CodegenCx::c_undef(Type::f32(bx.cx())),
|
32 => bx.cx().c_undef(Type::f32(bx.cx())),
|
||||||
64 => CodegenCx::c_undef(Type::f64(bx.cx())),
|
64 => bx.cx().c_undef(Type::f64(bx.cx())),
|
||||||
v => {
|
v => {
|
||||||
return_error!(r#"
|
return_error!(r#"
|
||||||
unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
|
unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
|
||||||
|
|
|
@ -96,7 +96,7 @@ pub fn get_vtable(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not in the cache. Build it.
|
// Not in the cache. Build it.
|
||||||
let nullptr = CodegenCx::c_null(Type::i8p(cx));
|
let nullptr = cx.c_null(Type::i8p(cx));
|
||||||
|
|
||||||
let methods = tcx.vtable_methods(trait_ref.with_self_ty(tcx, ty));
|
let methods = tcx.vtable_methods(trait_ref.with_self_ty(tcx, ty));
|
||||||
let methods = methods.iter().cloned().map(|opt_mth| {
|
let methods = methods.iter().cloned().map(|opt_mth| {
|
||||||
|
|
|
@ -172,7 +172,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
slot.storage_dead(&bx);
|
slot.storage_dead(&bx);
|
||||||
|
|
||||||
if !bx.sess().target.target.options.custom_unwind_resume {
|
if !bx.sess().target.target.options.custom_unwind_resume {
|
||||||
let mut lp = CodegenCx::c_undef(self.landing_pad_type());
|
let mut lp = bx.cx().c_undef(self.landing_pad_type());
|
||||||
lp = bx.insert_value(lp, lp0, 0);
|
lp = bx.insert_value(lp, lp0, 0);
|
||||||
lp = bx.insert_value(lp, lp1, 1);
|
lp = bx.insert_value(lp, lp1, 1);
|
||||||
bx.resume(lp);
|
bx.resume(lp);
|
||||||
|
@ -210,7 +210,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let switch_llty = bx.cx().layout_of(switch_ty).immediate_llvm_type(bx.cx());
|
let switch_llty = bx.cx().layout_of(switch_ty).immediate_llvm_type(bx.cx());
|
||||||
let llval = CodegenCx::c_uint_big(switch_llty, values[0]);
|
let llval = bx.cx().c_uint_big(switch_llty, values[0]);
|
||||||
let cmp = bx.icmp(IntPredicate::IntEQ, discr.immediate(), llval);
|
let cmp = bx.icmp(IntPredicate::IntEQ, discr.immediate(), llval);
|
||||||
bx.cond_br(cmp, lltrue, llfalse);
|
bx.cond_br(cmp, lltrue, llfalse);
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
values.len());
|
values.len());
|
||||||
let switch_llty = bx.cx().layout_of(switch_ty).immediate_llvm_type(bx.cx());
|
let switch_llty = bx.cx().layout_of(switch_ty).immediate_llvm_type(bx.cx());
|
||||||
for (&value, target) in values.iter().zip(targets) {
|
for (&value, target) in values.iter().zip(targets) {
|
||||||
let llval = CodegenCx::c_uint_big(switch_llty, value);
|
let llval =bx.cx().c_uint_big(switch_llty, value);
|
||||||
let llbb = llblock(self, *target);
|
let llbb = llblock(self, *target);
|
||||||
bx.add_case(switch, llval, llbb)
|
bx.add_case(switch, llval, llbb)
|
||||||
}
|
}
|
||||||
|
@ -563,7 +563,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
let dest = match ret_dest {
|
let dest = match ret_dest {
|
||||||
_ if fn_ty.ret.is_indirect() => llargs[0],
|
_ if fn_ty.ret.is_indirect() => llargs[0],
|
||||||
ReturnDest::Nothing => {
|
ReturnDest::Nothing => {
|
||||||
CodegenCx::c_undef(fn_ty.ret.memory_ty(bx.cx()).ptr_to())
|
bx.cx().c_undef(fn_ty.ret.memory_ty(bx.cx()).ptr_to())
|
||||||
}
|
}
|
||||||
ReturnDest::IndirectOperand(dst, _) |
|
ReturnDest::IndirectOperand(dst, _) |
|
||||||
ReturnDest::Store(dst) => dst.llval,
|
ReturnDest::Store(dst) => dst.llval,
|
||||||
|
@ -744,7 +744,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
arg: &ArgType<'tcx, Ty<'tcx>>) {
|
arg: &ArgType<'tcx, Ty<'tcx>>) {
|
||||||
// Fill padding with undef value, where applicable.
|
// Fill padding with undef value, where applicable.
|
||||||
if let Some(ty) = arg.pad {
|
if let Some(ty) = arg.pad {
|
||||||
llargs.push(CodegenCx::c_undef(ty.llvm_type(bx.cx())));
|
llargs.push(bx.cx().c_undef(ty.llvm_type(bx.cx())));
|
||||||
}
|
}
|
||||||
|
|
||||||
if arg.is_ignore() {
|
if arg.is_ignore() {
|
||||||
|
|
|
@ -40,11 +40,11 @@ pub fn scalar_to_llvm(
|
||||||
match cv {
|
match cv {
|
||||||
Scalar::Bits { size: 0, .. } => {
|
Scalar::Bits { size: 0, .. } => {
|
||||||
assert_eq!(0, layout.value.size(cx).bytes());
|
assert_eq!(0, layout.value.size(cx).bytes());
|
||||||
CodegenCx::c_undef(Type::ix(cx, 0))
|
cx.c_undef(Type::ix(cx, 0))
|
||||||
},
|
},
|
||||||
Scalar::Bits { bits, size } => {
|
Scalar::Bits { bits, size } => {
|
||||||
assert_eq!(size as u64, layout.value.size(cx).bytes());
|
assert_eq!(size as u64, layout.value.size(cx).bytes());
|
||||||
let llval = CodegenCx::c_uint_big(Type::ix(cx, bitsize), bits);
|
let llval = cx.c_uint_big(Type::ix(cx, bitsize), bits);
|
||||||
if layout.value == layout::Pointer {
|
if layout.value == layout::Pointer {
|
||||||
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
|
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
|
||||||
} else {
|
} else {
|
||||||
|
@ -73,7 +73,7 @@ pub fn scalar_to_llvm(
|
||||||
};
|
};
|
||||||
let llval = unsafe { llvm::LLVMConstInBoundsGEP(
|
let llval = unsafe { llvm::LLVMConstInBoundsGEP(
|
||||||
consts::bitcast(base_addr, Type::i8p(cx)),
|
consts::bitcast(base_addr, Type::i8p(cx)),
|
||||||
&CodegenCx::c_usize(cx, ptr.offset.bytes()),
|
&cx.c_usize(ptr.offset.bytes()),
|
||||||
1,
|
1,
|
||||||
) };
|
) };
|
||||||
if layout.value != layout::Pointer {
|
if layout.value != layout::Pointer {
|
||||||
|
@ -218,7 +218,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
// We've errored, so we don't have to produce working code.
|
// We've errored, so we don't have to produce working code.
|
||||||
let ty = self.monomorphize(&ty);
|
let ty = self.monomorphize(&ty);
|
||||||
let llty = bx.cx().layout_of(ty).llvm_type(bx.cx());
|
let llty = bx.cx().layout_of(ty).llvm_type(bx.cx());
|
||||||
(CodegenCx::c_undef(llty), ty)
|
(bx.cx().c_undef(llty), ty)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -420,7 +420,7 @@ fn create_funclets(
|
||||||
// C++ personality function, but `catch (...)` has no type so
|
// C++ personality function, but `catch (...)` has no type so
|
||||||
// it's null. The 64 here is actually a bitfield which
|
// it's null. The 64 here is actually a bitfield which
|
||||||
// represents that this is a catch-all block.
|
// represents that this is a catch-all block.
|
||||||
let null = CodegenCx::c_null(Type::i8p(bx.cx()));
|
let null = bx.cx().c_null(Type::i8p(bx.cx()));
|
||||||
let sixty_four = CodegenCx::c_i32(bx.cx(), 64);
|
let sixty_four = CodegenCx::c_i32(bx.cx(), 64);
|
||||||
cleanup = cp_bx.catch_pad(cs, &[null, sixty_four, null]);
|
cleanup = cp_bx.catch_pad(cs, &[null, sixty_four, null]);
|
||||||
cp_bx.br(llbb);
|
cp_bx.br(llbb);
|
||||||
|
|
|
@ -73,7 +73,7 @@ impl OperandRef<'tcx, &'ll Value> {
|
||||||
layout: TyLayout<'tcx>) -> OperandRef<'tcx, &'ll Value> {
|
layout: TyLayout<'tcx>) -> OperandRef<'tcx, &'ll Value> {
|
||||||
assert!(layout.is_zst());
|
assert!(layout.is_zst());
|
||||||
OperandRef {
|
OperandRef {
|
||||||
val: OperandValue::Immediate(CodegenCx::c_undef(layout.immediate_llvm_type(cx))),
|
val: OperandValue::Immediate(cx.c_undef(layout.immediate_llvm_type(cx))),
|
||||||
layout
|
layout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ impl OperandRef<'tcx, &'ll Value> {
|
||||||
debug!("Operand::immediate_or_packed_pair: packing {:?} into {:?}",
|
debug!("Operand::immediate_or_packed_pair: packing {:?} into {:?}",
|
||||||
self, llty);
|
self, llty);
|
||||||
// Reconstruct the immediate aggregate.
|
// Reconstruct the immediate aggregate.
|
||||||
let mut llpair = CodegenCx::c_undef(llty);
|
let mut llpair = bx.cx().c_undef(llty);
|
||||||
llpair = bx.insert_value(llpair, base::from_immediate(bx, a), 0);
|
llpair = bx.insert_value(llpair, base::from_immediate(bx, a), 0);
|
||||||
llpair = bx.insert_value(llpair, base::from_immediate(bx, b), 1);
|
llpair = bx.insert_value(llpair, base::from_immediate(bx, b), 1);
|
||||||
llpair
|
llpair
|
||||||
|
@ -232,7 +232,7 @@ impl OperandRef<'tcx, &'ll Value> {
|
||||||
// `#[repr(simd)]` types are also immediate.
|
// `#[repr(simd)]` types are also immediate.
|
||||||
(OperandValue::Immediate(llval), &layout::Abi::Vector { .. }) => {
|
(OperandValue::Immediate(llval), &layout::Abi::Vector { .. }) => {
|
||||||
OperandValue::Immediate(
|
OperandValue::Immediate(
|
||||||
bx.extract_element(llval, CodegenCx::c_usize(bx.cx(), i as u64)))
|
bx.extract_element(llval, bx.cx().c_usize(i as u64)))
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => bug!("OperandRef::extract_field({:?}): not applicable", self)
|
_ => bug!("OperandRef::extract_field({:?}): not applicable", self)
|
||||||
|
@ -463,7 +463,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
// We've errored, so we don't have to produce working code.
|
// We've errored, so we don't have to produce working code.
|
||||||
let layout = bx.cx().layout_of(ty);
|
let layout = bx.cx().layout_of(ty);
|
||||||
PlaceRef::new_sized(
|
PlaceRef::new_sized(
|
||||||
CodegenCx::c_undef(layout.llvm_type(bx.cx()).ptr_to()),
|
bx.cx().c_undef(layout.llvm_type(bx.cx()).ptr_to()),
|
||||||
layout,
|
layout,
|
||||||
layout.align,
|
layout.align,
|
||||||
).load(bx)
|
).load(bx)
|
||||||
|
|
|
@ -69,7 +69,7 @@ impl PlaceRef<'tcx, &'ll Value> {
|
||||||
|
|
||||||
let llval = unsafe { LLVMConstInBoundsGEP(
|
let llval = unsafe { LLVMConstInBoundsGEP(
|
||||||
consts::bitcast(base_addr, Type::i8p(bx.cx())),
|
consts::bitcast(base_addr, Type::i8p(bx.cx())),
|
||||||
&CodegenCx::c_usize(bx.cx(), offset.bytes()),
|
&bx.cx().c_usize(offset.bytes()),
|
||||||
1,
|
1,
|
||||||
)};
|
)};
|
||||||
let llval = consts::bitcast(llval, layout.llvm_type(bx.cx()).ptr_to());
|
let llval = consts::bitcast(llval, layout.llvm_type(bx.cx()).ptr_to());
|
||||||
|
@ -103,7 +103,7 @@ impl PlaceRef<'tcx, &'ll Value> {
|
||||||
assert_eq!(count, 0);
|
assert_eq!(count, 0);
|
||||||
self.llextra.unwrap()
|
self.llextra.unwrap()
|
||||||
} else {
|
} else {
|
||||||
CodegenCx::c_usize(cx, count)
|
cx.c_usize(count)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bug!("unexpected layout `{:#?}` in PlaceRef::len", self.layout)
|
bug!("unexpected layout `{:#?}` in PlaceRef::len", self.layout)
|
||||||
|
@ -248,7 +248,7 @@ impl PlaceRef<'tcx, &'ll Value> {
|
||||||
|
|
||||||
let meta = self.llextra;
|
let meta = self.llextra;
|
||||||
|
|
||||||
let unaligned_offset = CodegenCx::c_usize(cx, offset.bytes());
|
let unaligned_offset = cx.c_usize(offset.bytes());
|
||||||
|
|
||||||
// Get the alignment of the field
|
// Get the alignment of the field
|
||||||
let (_, unsized_align) = glue::size_and_align_of_dst(bx, field.ty, meta);
|
let (_, unsized_align) = glue::size_and_align_of_dst(bx, field.ty, meta);
|
||||||
|
@ -259,7 +259,7 @@ impl PlaceRef<'tcx, &'ll Value> {
|
||||||
// (unaligned offset + (align - 1)) & -align
|
// (unaligned offset + (align - 1)) & -align
|
||||||
|
|
||||||
// Calculate offset
|
// Calculate offset
|
||||||
let align_sub_1 = bx.sub(unsized_align, CodegenCx::c_usize(cx, 1u64));
|
let align_sub_1 = bx.sub(unsized_align, cx.c_usize(1u64));
|
||||||
let offset = bx.and(bx.add(unaligned_offset, align_sub_1),
|
let offset = bx.and(bx.add(unaligned_offset, align_sub_1),
|
||||||
bx.neg(unsized_align));
|
bx.neg(unsized_align));
|
||||||
|
|
||||||
|
@ -289,14 +289,14 @@ impl PlaceRef<'tcx, &'ll Value> {
|
||||||
) -> &'ll Value {
|
) -> &'ll Value {
|
||||||
let cast_to = bx.cx().layout_of(cast_to).immediate_llvm_type(bx.cx());
|
let cast_to = bx.cx().layout_of(cast_to).immediate_llvm_type(bx.cx());
|
||||||
if self.layout.abi.is_uninhabited() {
|
if self.layout.abi.is_uninhabited() {
|
||||||
return CodegenCx::c_undef(cast_to);
|
return bx.cx().c_undef(cast_to);
|
||||||
}
|
}
|
||||||
match self.layout.variants {
|
match self.layout.variants {
|
||||||
layout::Variants::Single { index } => {
|
layout::Variants::Single { index } => {
|
||||||
let discr_val = self.layout.ty.ty_adt_def().map_or(
|
let discr_val = self.layout.ty.ty_adt_def().map_or(
|
||||||
index.as_u32() as u128,
|
index.as_u32() as u128,
|
||||||
|def| def.discriminant_for_variant(bx.cx().tcx, index).val);
|
|def| def.discriminant_for_variant(bx.cx().tcx, index).val);
|
||||||
return CodegenCx::c_uint_big(cast_to, discr_val);
|
return bx.cx().c_uint_big(cast_to, discr_val);
|
||||||
}
|
}
|
||||||
layout::Variants::Tagged { .. } |
|
layout::Variants::Tagged { .. } |
|
||||||
layout::Variants::NicheFilling { .. } => {},
|
layout::Variants::NicheFilling { .. } => {},
|
||||||
|
@ -328,22 +328,22 @@ impl PlaceRef<'tcx, &'ll Value> {
|
||||||
// FIXME(eddyb) Check the actual primitive type here.
|
// FIXME(eddyb) Check the actual primitive type here.
|
||||||
let niche_llval = if niche_start == 0 {
|
let niche_llval = if niche_start == 0 {
|
||||||
// HACK(eddyb) Using `c_null` as it works on all types.
|
// HACK(eddyb) Using `c_null` as it works on all types.
|
||||||
CodegenCx::c_null(niche_llty)
|
bx.cx().c_null(niche_llty)
|
||||||
} else {
|
} else {
|
||||||
CodegenCx::c_uint_big(niche_llty, niche_start)
|
bx.cx().c_uint_big(niche_llty, niche_start)
|
||||||
};
|
};
|
||||||
bx.select(bx.icmp(IntPredicate::IntEQ, lldiscr, niche_llval),
|
bx.select(bx.icmp(IntPredicate::IntEQ, lldiscr, niche_llval),
|
||||||
CodegenCx::c_uint(cast_to, niche_variants.start().as_u32() as u64),
|
bx.cx().c_uint(cast_to, niche_variants.start().as_u32() as u64),
|
||||||
CodegenCx::c_uint(cast_to, dataful_variant.as_u32() as u64))
|
bx.cx().c_uint(cast_to, dataful_variant.as_u32() as u64))
|
||||||
} else {
|
} else {
|
||||||
// Rebase from niche values to discriminant values.
|
// Rebase from niche values to discriminant values.
|
||||||
let delta = niche_start.wrapping_sub(niche_variants.start().as_u32() as u128);
|
let delta = niche_start.wrapping_sub(niche_variants.start().as_u32() as u128);
|
||||||
let lldiscr = bx.sub(lldiscr, CodegenCx::c_uint_big(niche_llty, delta));
|
let lldiscr = bx.sub(lldiscr, bx.cx().c_uint_big(niche_llty, delta));
|
||||||
let lldiscr_max =
|
let lldiscr_max =
|
||||||
CodegenCx::c_uint(niche_llty, niche_variants.end().as_u32() as u64);
|
bx.cx().c_uint(niche_llty, niche_variants.end().as_u32() as u64);
|
||||||
bx.select(bx.icmp(IntPredicate::IntULE, lldiscr, lldiscr_max),
|
bx.select(bx.icmp(IntPredicate::IntULE, lldiscr, lldiscr_max),
|
||||||
bx.intcast(lldiscr, cast_to, false),
|
bx.intcast(lldiscr, cast_to, false),
|
||||||
CodegenCx::c_uint(cast_to, dataful_variant.as_u32() as u64))
|
bx.cx().c_uint(cast_to, dataful_variant.as_u32() as u64))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -365,7 +365,7 @@ impl PlaceRef<'tcx, &'ll Value> {
|
||||||
.discriminant_for_variant(bx.tcx(), variant_index)
|
.discriminant_for_variant(bx.tcx(), variant_index)
|
||||||
.val;
|
.val;
|
||||||
bx.store(
|
bx.store(
|
||||||
CodegenCx::c_uint_big(ptr.layout.llvm_type(bx.cx()), to),
|
bx.cx().c_uint_big(ptr.layout.llvm_type(bx.cx()), to),
|
||||||
ptr.llval,
|
ptr.llval,
|
||||||
ptr.align);
|
ptr.align);
|
||||||
}
|
}
|
||||||
|
@ -381,10 +381,10 @@ impl PlaceRef<'tcx, &'ll Value> {
|
||||||
// Issue #34427: As workaround for LLVM bug on ARM,
|
// Issue #34427: As workaround for LLVM bug on ARM,
|
||||||
// use memset of 0 before assigning niche value.
|
// use memset of 0 before assigning niche value.
|
||||||
let llptr = bx.pointercast(self.llval, Type::i8(bx.cx()).ptr_to());
|
let llptr = bx.pointercast(self.llval, Type::i8(bx.cx()).ptr_to());
|
||||||
let fill_byte = CodegenCx::c_u8(bx.cx(), 0);
|
let fill_byte = bx.cx().c_u8(0);
|
||||||
let (size, align) = self.layout.size_and_align();
|
let (size, align) = self.layout.size_and_align();
|
||||||
let size = CodegenCx::c_usize(bx.cx(), size.bytes());
|
let size = bx.cx().c_usize(size.bytes());
|
||||||
let align = CodegenCx::c_u32(bx.cx(), align.abi() as u32);
|
let align = bx.cx().c_u32(align.abi() as u32);
|
||||||
base::call_memset(bx, llptr, fill_byte, size, align, false);
|
base::call_memset(bx, llptr, fill_byte, size, align, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,9 +396,9 @@ impl PlaceRef<'tcx, &'ll Value> {
|
||||||
// FIXME(eddyb) Check the actual primitive type here.
|
// FIXME(eddyb) Check the actual primitive type here.
|
||||||
let niche_llval = if niche_value == 0 {
|
let niche_llval = if niche_value == 0 {
|
||||||
// HACK(eddyb) Using `c_null` as it works on all types.
|
// HACK(eddyb) Using `c_null` as it works on all types.
|
||||||
CodegenCx::c_null(niche_llty)
|
bx.cx().c_null(niche_llty)
|
||||||
} else {
|
} else {
|
||||||
CodegenCx::c_uint_big(niche_llty, niche_value)
|
bx.cx().c_uint_big(niche_llty, niche_value)
|
||||||
};
|
};
|
||||||
OperandValue::Immediate(niche_llval).store(bx, niche);
|
OperandValue::Immediate(niche_llval).store(bx, niche);
|
||||||
}
|
}
|
||||||
|
@ -409,7 +409,7 @@ impl PlaceRef<'tcx, &'ll Value> {
|
||||||
pub fn project_index(&self, bx: &Builder<'a, 'll, 'tcx>, llindex: &'ll Value)
|
pub fn project_index(&self, bx: &Builder<'a, 'll, 'tcx>, llindex: &'ll Value)
|
||||||
-> PlaceRef<'tcx, &'ll Value> {
|
-> PlaceRef<'tcx, &'ll Value> {
|
||||||
PlaceRef {
|
PlaceRef {
|
||||||
llval: bx.inbounds_gep(self.llval, &[CodegenCx::c_usize(bx.cx(), 0), llindex]),
|
llval: bx.inbounds_gep(self.llval, &[bx.cx().c_usize(0), llindex]),
|
||||||
llextra: None,
|
llextra: None,
|
||||||
layout: self.layout.field(bx.cx(), 0),
|
layout: self.layout.field(bx.cx(), 0),
|
||||||
align: self.align
|
align: self.align
|
||||||
|
@ -484,7 +484,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
// so we generate an abort
|
// so we generate an abort
|
||||||
let fnname = bx.cx().get_intrinsic(&("llvm.trap"));
|
let fnname = bx.cx().get_intrinsic(&("llvm.trap"));
|
||||||
bx.call(fnname, &[], None);
|
bx.call(fnname, &[], None);
|
||||||
let llval = CodegenCx::c_undef(layout.llvm_type(bx.cx()).ptr_to());
|
let llval = bx.cx().c_undef(layout.llvm_type(bx.cx()).ptr_to());
|
||||||
PlaceRef::new_sized(llval, layout, layout.align)
|
PlaceRef::new_sized(llval, layout, layout.align)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -517,20 +517,20 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
mir::ProjectionElem::ConstantIndex { offset,
|
mir::ProjectionElem::ConstantIndex { offset,
|
||||||
from_end: false,
|
from_end: false,
|
||||||
min_length: _ } => {
|
min_length: _ } => {
|
||||||
let lloffset = CodegenCx::c_usize(bx.cx(), offset as u64);
|
let lloffset = bx.cx().c_usize(offset as u64);
|
||||||
cg_base.project_index(bx, lloffset)
|
cg_base.project_index(bx, lloffset)
|
||||||
}
|
}
|
||||||
mir::ProjectionElem::ConstantIndex { offset,
|
mir::ProjectionElem::ConstantIndex { offset,
|
||||||
from_end: true,
|
from_end: true,
|
||||||
min_length: _ } => {
|
min_length: _ } => {
|
||||||
let lloffset = CodegenCx::c_usize(bx.cx(), offset as u64);
|
let lloffset = bx.cx().c_usize(offset as u64);
|
||||||
let lllen = cg_base.len(bx.cx());
|
let lllen = cg_base.len(bx.cx());
|
||||||
let llindex = bx.sub(lllen, lloffset);
|
let llindex = bx.sub(lllen, lloffset);
|
||||||
cg_base.project_index(bx, llindex)
|
cg_base.project_index(bx, llindex)
|
||||||
}
|
}
|
||||||
mir::ProjectionElem::Subslice { from, to } => {
|
mir::ProjectionElem::Subslice { from, to } => {
|
||||||
let mut subslice = cg_base.project_index(bx,
|
let mut subslice = cg_base.project_index(bx,
|
||||||
CodegenCx::c_usize(bx.cx(), from as u64));
|
bx.cx().c_usize(from as u64));
|
||||||
let projected_ty = PlaceTy::Ty { ty: cg_base.layout.ty }
|
let projected_ty = PlaceTy::Ty { ty: cg_base.layout.ty }
|
||||||
.projection_ty(tcx, &projection.elem)
|
.projection_ty(tcx, &projection.elem)
|
||||||
.to_ty(bx.tcx());
|
.to_ty(bx.tcx());
|
||||||
|
@ -538,7 +538,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
|
|
||||||
if subslice.layout.is_unsized() {
|
if subslice.layout.is_unsized() {
|
||||||
subslice.llextra = Some(bx.sub(cg_base.llextra.unwrap(),
|
subslice.llextra = Some(bx.sub(cg_base.llextra.unwrap(),
|
||||||
CodegenCx::c_usize(bx.cx(), (from as u64) + (to as u64))));
|
bx.cx().c_usize((from as u64) + (to as u64))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cast the place pointer type to the new
|
// Cast the place pointer type to the new
|
||||||
|
|
|
@ -103,15 +103,15 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
return bx;
|
return bx;
|
||||||
}
|
}
|
||||||
|
|
||||||
let start = dest.project_index(&bx, CodegenCx::c_usize(bx.cx(), 0)).llval;
|
let start = dest.project_index(&bx, bx.cx().c_usize(0)).llval;
|
||||||
|
|
||||||
if let OperandValue::Immediate(v) = cg_elem.val {
|
if let OperandValue::Immediate(v) = cg_elem.val {
|
||||||
let align = CodegenCx::c_i32(bx.cx(), dest.align.abi() as i32);
|
let align = bx.cx().c_i32(dest.align.abi() as i32);
|
||||||
let size = CodegenCx::c_usize(bx.cx(), dest.layout.size.bytes());
|
let size = bx.cx().c_usize(dest.layout.size.bytes());
|
||||||
|
|
||||||
// Use llvm.memset.p0i8.* to initialize all zero arrays
|
// Use llvm.memset.p0i8.* to initialize all zero arrays
|
||||||
if CodegenCx::is_const_integral(v) && CodegenCx::const_to_uint(v) == 0 {
|
if CodegenCx::is_const_integral(v) && CodegenCx::const_to_uint(v) == 0 {
|
||||||
let fill = CodegenCx::c_u8(bx.cx(), 0);
|
let fill = bx.cx().c_u8(0);
|
||||||
base::call_memset(&bx, start, fill, size, align, false);
|
base::call_memset(&bx, start, fill, size, align, false);
|
||||||
return bx;
|
return bx;
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let count = CodegenCx::c_usize(bx.cx(), count);
|
let count = bx.cx().c_usize(count);
|
||||||
let end = dest.project_index(&bx, count).llval;
|
let end = dest.project_index(&bx, count).llval;
|
||||||
|
|
||||||
let header_bx = bx.build_sibling_block("repeat_loop_header");
|
let header_bx = bx.build_sibling_block("repeat_loop_header");
|
||||||
|
@ -140,7 +140,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
cg_elem.val.store(&body_bx,
|
cg_elem.val.store(&body_bx,
|
||||||
PlaceRef::new_sized(current, cg_elem.layout, dest.align));
|
PlaceRef::new_sized(current, cg_elem.layout, dest.align));
|
||||||
|
|
||||||
let next = body_bx.inbounds_gep(current, &[CodegenCx::c_usize(bx.cx(), 1)]);
|
let next = body_bx.inbounds_gep(current, &[bx.cx().c_usize(1)]);
|
||||||
body_bx.br(header_bx.llbb());
|
body_bx.br(header_bx.llbb());
|
||||||
header_bx.add_incoming_to_phi(current, next, body_bx.llbb());
|
header_bx.add_incoming_to_phi(current, next, body_bx.llbb());
|
||||||
|
|
||||||
|
@ -292,8 +292,9 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
assert!(cast.is_llvm_immediate());
|
assert!(cast.is_llvm_immediate());
|
||||||
let ll_t_out = cast.immediate_llvm_type(bx.cx());
|
let ll_t_out = cast.immediate_llvm_type(bx.cx());
|
||||||
if operand.layout.abi.is_uninhabited() {
|
if operand.layout.abi.is_uninhabited() {
|
||||||
|
let val = OperandValue::Immediate(bx.cx().c_undef(ll_t_out));
|
||||||
return (bx, OperandRef {
|
return (bx, OperandRef {
|
||||||
val: OperandValue::Immediate(CodegenCx::c_undef(ll_t_out)),
|
val,
|
||||||
layout: cast,
|
layout: cast,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -307,7 +308,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
let discr_val = def
|
let discr_val = def
|
||||||
.discriminant_for_variant(bx.cx().tcx, index)
|
.discriminant_for_variant(bx.cx().tcx, index)
|
||||||
.val;
|
.val;
|
||||||
let discr = CodegenCx::c_uint_big(ll_t_out, discr_val);
|
let discr = bx.cx().c_uint_big(ll_t_out, discr_val);
|
||||||
return (bx, OperandRef {
|
return (bx, OperandRef {
|
||||||
val: OperandValue::Immediate(discr),
|
val: OperandValue::Immediate(discr),
|
||||||
layout: cast,
|
layout: cast,
|
||||||
|
@ -338,7 +339,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
base::call_assume(&bx, bx.icmp(
|
base::call_assume(&bx, bx.icmp(
|
||||||
IntPredicate::IntULE,
|
IntPredicate::IntULE,
|
||||||
llval,
|
llval,
|
||||||
CodegenCx::c_uint_big(ll_t_in, *scalar.valid_range.end())
|
bx.cx().c_uint_big(ll_t_in, *scalar.valid_range.end())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -489,7 +490,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
|
|
||||||
mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
|
mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
|
||||||
assert!(bx.cx().type_is_sized(ty));
|
assert!(bx.cx().type_is_sized(ty));
|
||||||
let val = CodegenCx::c_usize(bx.cx(), bx.cx().size_of(ty).bytes());
|
let val = bx.cx().c_usize(bx.cx().size_of(ty).bytes());
|
||||||
let tcx = bx.tcx();
|
let tcx = bx.tcx();
|
||||||
(bx, OperandRef {
|
(bx, OperandRef {
|
||||||
val: OperandValue::Immediate(val),
|
val: OperandValue::Immediate(val),
|
||||||
|
@ -500,8 +501,8 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
mir::Rvalue::NullaryOp(mir::NullOp::Box, content_ty) => {
|
mir::Rvalue::NullaryOp(mir::NullOp::Box, content_ty) => {
|
||||||
let content_ty: Ty<'tcx> = self.monomorphize(&content_ty);
|
let content_ty: Ty<'tcx> = self.monomorphize(&content_ty);
|
||||||
let (size, align) = bx.cx().size_and_align_of(content_ty);
|
let (size, align) = bx.cx().size_and_align_of(content_ty);
|
||||||
let llsize = CodegenCx::c_usize(bx.cx(), size.bytes());
|
let llsize = bx.cx().c_usize(size.bytes());
|
||||||
let llalign = CodegenCx::c_usize(bx.cx(), align.abi());
|
let llalign = bx.cx().c_usize(align.abi());
|
||||||
let box_layout = bx.cx().layout_of(bx.tcx().mk_box(content_ty));
|
let box_layout = bx.cx().layout_of(bx.tcx().mk_box(content_ty));
|
||||||
let llty_ptr = box_layout.llvm_type(bx.cx());
|
let llty_ptr = box_layout.llvm_type(bx.cx());
|
||||||
|
|
||||||
|
@ -548,7 +549,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
if let LocalRef::Operand(Some(op)) = self.locals[index] {
|
if let LocalRef::Operand(Some(op)) = self.locals[index] {
|
||||||
if let ty::Array(_, n) = op.layout.ty.sty {
|
if let ty::Array(_, n) = op.layout.ty.sty {
|
||||||
let n = n.unwrap_usize(bx.cx().tcx);
|
let n = n.unwrap_usize(bx.cx().tcx);
|
||||||
return CodegenCx::c_usize(bx.cx(), n);
|
return bx.cx().c_usize(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -606,7 +607,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
mir::BinOp::Shr => common::build_unchecked_rshift(bx, input_ty, lhs, rhs),
|
mir::BinOp::Shr => common::build_unchecked_rshift(bx, input_ty, lhs, rhs),
|
||||||
mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt |
|
mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt |
|
||||||
mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => if is_unit {
|
mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => if is_unit {
|
||||||
CodegenCx::c_bool(bx.cx(), match op {
|
bx.cx().c_bool(match op {
|
||||||
mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt => false,
|
mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt => false,
|
||||||
mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => true,
|
mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => true,
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
|
@ -685,7 +686,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
// while the current crate doesn't use overflow checks.
|
// while the current crate doesn't use overflow checks.
|
||||||
if !bx.cx().check_overflow {
|
if !bx.cx().check_overflow {
|
||||||
let val = self.codegen_scalar_binop(bx, op, lhs, rhs, input_ty);
|
let val = self.codegen_scalar_binop(bx, op, lhs, rhs, input_ty);
|
||||||
return OperandValue::Pair(val, CodegenCx::c_bool(bx.cx(), false));
|
return OperandValue::Pair(val, bx.cx().c_bool(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (val, of) = match op {
|
let (val, of) = match op {
|
||||||
|
@ -709,7 +710,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
let invert_mask = common::shift_mask_val(&bx, lhs_llty, rhs_llty, true);
|
let invert_mask = common::shift_mask_val(&bx, lhs_llty, rhs_llty, true);
|
||||||
let outer_bits = bx.and(rhs, invert_mask);
|
let outer_bits = bx.and(rhs, invert_mask);
|
||||||
|
|
||||||
let of = bx.icmp(IntPredicate::IntNE, outer_bits, CodegenCx::c_null(rhs_llty));
|
let of = bx.icmp(IntPredicate::IntNE, outer_bits, bx.cx().c_null(rhs_llty));
|
||||||
let val = self.codegen_scalar_binop(bx, op, lhs, rhs, input_ty);
|
let val = self.codegen_scalar_binop(bx, op, lhs, rhs, input_ty);
|
||||||
|
|
||||||
(val, of)
|
(val, of)
|
||||||
|
@ -836,9 +837,9 @@ fn cast_int_to_float(bx: &Builder<'_, 'll, '_>,
|
||||||
use rustc_apfloat::Float;
|
use rustc_apfloat::Float;
|
||||||
const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1)
|
const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1)
|
||||||
<< (Single::MAX_EXP - Single::PRECISION as i16);
|
<< (Single::MAX_EXP - Single::PRECISION as i16);
|
||||||
let max = CodegenCx::c_uint_big(int_ty, MAX_F32_PLUS_HALF_ULP);
|
let max = bx.cx().c_uint_big(int_ty, MAX_F32_PLUS_HALF_ULP);
|
||||||
let overflow = bx.icmp(IntPredicate::IntUGE, x, max);
|
let overflow = bx.icmp(IntPredicate::IntUGE, x, max);
|
||||||
let infinity_bits = CodegenCx::c_u32(bx.cx(), ieee::Single::INFINITY.to_bits() as u32);
|
let infinity_bits = bx.cx().c_u32(ieee::Single::INFINITY.to_bits() as u32);
|
||||||
let infinity = consts::bitcast(infinity_bits, float_ty);
|
let infinity = consts::bitcast(infinity_bits, float_ty);
|
||||||
bx.select(overflow, infinity, bx.uitofp(x, float_ty))
|
bx.select(overflow, infinity, bx.uitofp(x, float_ty))
|
||||||
} else {
|
} else {
|
||||||
|
@ -907,8 +908,8 @@ fn cast_float_to_int(bx: &Builder<'_, 'll, '_>,
|
||||||
}
|
}
|
||||||
let float_bits_to_llval = |bits| {
|
let float_bits_to_llval = |bits| {
|
||||||
let bits_llval = match float_ty.float_width() {
|
let bits_llval = match float_ty.float_width() {
|
||||||
32 => CodegenCx::c_u32(bx.cx(), bits as u32),
|
32 => bx.cx().c_u32(bits as u32),
|
||||||
64 => CodegenCx::c_u64(bx.cx(), bits as u64),
|
64 => bx.cx().c_u64(bits as u64),
|
||||||
n => bug!("unsupported float width {}", n),
|
n => bug!("unsupported float width {}", n),
|
||||||
};
|
};
|
||||||
consts::bitcast(bits_llval, float_ty)
|
consts::bitcast(bits_llval, float_ty)
|
||||||
|
@ -963,8 +964,8 @@ fn cast_float_to_int(bx: &Builder<'_, 'll, '_>,
|
||||||
// performed is ultimately up to the backend, but at least x86 does perform them.
|
// performed is ultimately up to the backend, but at least x86 does perform them.
|
||||||
let less_or_nan = bx.fcmp(RealPredicate::RealULT, x, f_min);
|
let less_or_nan = bx.fcmp(RealPredicate::RealULT, x, f_min);
|
||||||
let greater = bx.fcmp(RealPredicate::RealOGT, x, f_max);
|
let greater = bx.fcmp(RealPredicate::RealOGT, x, f_max);
|
||||||
let int_max = CodegenCx::c_uint_big(int_ty, int_max(signed, int_ty));
|
let int_max = bx.cx().c_uint_big(int_ty, int_max(signed, int_ty));
|
||||||
let int_min = CodegenCx::c_uint_big(int_ty, int_min(signed, int_ty) as u128);
|
let int_min = bx.cx().c_uint_big(int_ty, int_min(signed, int_ty) as u128);
|
||||||
let s0 = bx.select(less_or_nan, int_min, fptosui_result);
|
let s0 = bx.select(less_or_nan, int_min, fptosui_result);
|
||||||
let s1 = bx.select(greater, int_max, s0);
|
let s1 = bx.select(greater, int_max, s0);
|
||||||
|
|
||||||
|
@ -973,7 +974,7 @@ fn cast_float_to_int(bx: &Builder<'_, 'll, '_>,
|
||||||
// Therefore we only need to execute this step for signed integer types.
|
// Therefore we only need to execute this step for signed integer types.
|
||||||
if signed {
|
if signed {
|
||||||
// LLVM has no isNaN predicate, so we use (x == x) instead
|
// LLVM has no isNaN predicate, so we use (x == x) instead
|
||||||
bx.select(bx.fcmp(RealPredicate::RealOEQ, x, x), s1, CodegenCx::c_uint(int_ty, 0))
|
bx.select(bx.fcmp(RealPredicate::RealOEQ, x, x), s1, bx.cx().c_uint(int_ty, 0))
|
||||||
} else {
|
} else {
|
||||||
s1
|
s1
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue