Skip to content

Commit 19a351c

Browse files
committed
Auto merge of #30586 - nagisa:mir-cast, r=arielb1
I think that should pretty much conclude all of #29576.
2 parents 5892852 + feab2ae commit 19a351c

File tree

2 files changed

+433
-1
lines changed

2 files changed

+433
-1
lines changed

src/librustc_trans/trans/mir/rvalue.rs

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use llvm::ValueRef;
1212
use rustc::middle::ty::{self, Ty};
13+
use middle::ty::cast::{CastTy, IntTy};
1314
use rustc::mir::repr as mir;
1415

1516
use trans::asm;
@@ -199,7 +200,89 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
199200
}
200201
}
201202
}
202-
mir::CastKind::Misc => unimplemented!()
203+
mir::CastKind::Misc if common::type_is_immediate(bcx.ccx(), operand.ty) => {
204+
debug_assert!(common::type_is_immediate(bcx.ccx(), cast_ty));
205+
let r_t_in = CastTy::from_ty(operand.ty).expect("bad input type for cast");
206+
let r_t_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
207+
let ll_t_in = type_of::arg_type_of(bcx.ccx(), operand.ty);
208+
let ll_t_out = type_of::arg_type_of(bcx.ccx(), cast_ty);
209+
let (llval, ll_t_in, signed) = if let CastTy::Int(IntTy::CEnum) = r_t_in {
210+
let repr = adt::represent_type(bcx.ccx(), operand.ty);
211+
let llval = operand.immediate();
212+
let discr = adt::trans_get_discr(bcx, &*repr, llval, None);
213+
(discr, common::val_ty(discr), adt::is_discr_signed(&*repr))
214+
} else {
215+
(operand.immediate(), ll_t_in, operand.ty.is_signed())
216+
};
217+
218+
let newval = match (r_t_in, r_t_out) {
219+
(CastTy::Int(_), CastTy::Int(_)) => {
220+
let srcsz = ll_t_in.int_width();
221+
let dstsz = ll_t_out.int_width();
222+
if srcsz == dstsz {
223+
build::BitCast(bcx, llval, ll_t_out)
224+
} else if srcsz > dstsz {
225+
build::Trunc(bcx, llval, ll_t_out)
226+
} else if signed {
227+
build::SExt(bcx, llval, ll_t_out)
228+
} else {
229+
build::ZExt(bcx, llval, ll_t_out)
230+
}
231+
}
232+
(CastTy::Float, CastTy::Float) => {
233+
let srcsz = ll_t_in.float_width();
234+
let dstsz = ll_t_out.float_width();
235+
if dstsz > srcsz {
236+
build::FPExt(bcx, llval, ll_t_out)
237+
} else if srcsz > dstsz {
238+
build::FPTrunc(bcx, llval, ll_t_out)
239+
} else {
240+
llval
241+
}
242+
}
243+
(CastTy::Ptr(_), CastTy::Ptr(_)) |
244+
(CastTy::FnPtr, CastTy::Ptr(_)) |
245+
(CastTy::RPtr(_), CastTy::Ptr(_)) =>
246+
build::PointerCast(bcx, llval, ll_t_out),
247+
(CastTy::Ptr(_), CastTy::Int(_)) |
248+
(CastTy::FnPtr, CastTy::Int(_)) =>
249+
build::PtrToInt(bcx, llval, ll_t_out),
250+
(CastTy::Int(_), CastTy::Ptr(_)) =>
251+
build::IntToPtr(bcx, llval, ll_t_out),
252+
(CastTy::Int(_), CastTy::Float) if signed =>
253+
build::SIToFP(bcx, llval, ll_t_out),
254+
(CastTy::Int(_), CastTy::Float) =>
255+
build::UIToFP(bcx, llval, ll_t_out),
256+
(CastTy::Float, CastTy::Int(IntTy::I)) =>
257+
build::FPToSI(bcx, llval, ll_t_out),
258+
(CastTy::Float, CastTy::Int(_)) =>
259+
build::FPToUI(bcx, llval, ll_t_out),
260+
_ => bcx.ccx().sess().bug(
261+
&format!("unsupported cast: {:?} to {:?}", operand.ty, cast_ty)
262+
)
263+
};
264+
OperandValue::Immediate(newval)
265+
}
266+
mir::CastKind::Misc => { // Casts from a fat-ptr.
267+
let ll_cast_ty = type_of::arg_type_of(bcx.ccx(), cast_ty);
268+
let ll_from_ty = type_of::arg_type_of(bcx.ccx(), operand.ty);
269+
if let OperandValue::FatPtr(data_ptr, meta_ptr) = operand.val {
270+
if common::type_is_fat_ptr(bcx.tcx(), cast_ty) {
271+
let ll_cft = ll_cast_ty.field_types();
272+
let ll_fft = ll_from_ty.field_types();
273+
let data_cast = build::PointerCast(bcx, data_ptr, ll_cft[0]);
274+
assert_eq!(ll_cft[1].kind(), ll_fft[1].kind());
275+
OperandValue::FatPtr(data_cast, meta_ptr)
276+
} else { // cast to thin-ptr
277+
// Cast of fat-ptr to thin-ptr is an extraction of data-ptr and
278+
// pointer-cast of that pointer to desired pointer type.
279+
let llval = build::PointerCast(bcx, data_ptr, ll_cast_ty);
280+
OperandValue::Immediate(llval)
281+
}
282+
} else {
283+
panic!("Unexpected non-FatPtr operand")
284+
}
285+
}
203286
};
204287
(bcx, OperandRef {
205288
val: val,

0 commit comments

Comments
 (0)