]> git.proxmox.com Git - rustc.git/blame - src/librustc_codegen_ssa/mir/statement.rs
New upstream version 1.33.0+dfsg1
[rustc.git] / src / librustc_codegen_ssa / mir / statement.rs
CommitLineData
c30ab7b3 1use rustc::mir;
3157f602 2
a1dfa0c6 3use traits::BuilderMethods;
2c00a5a8 4use super::FunctionCx;
3157f602 5use super::LocalRef;
0bf4aa26 6use super::OperandValue;
a1dfa0c6 7use traits::*;
92a42be0 8
a1dfa0c6
XL
9impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10 pub fn codegen_statement(
11 &mut self,
12 mut bx: Bx,
13 statement: &mir::Statement<'tcx>
14 ) -> Bx {
94b46f34 15 debug!("codegen_statement(statement={:?})", statement);
92a42be0 16
a1dfa0c6 17 self.set_debug_loc(&mut bx, statement.source_info);
92a42be0 18 match statement.kind {
ff7c6d11
XL
19 mir::StatementKind::Assign(ref place, ref rvalue) => {
20 if let mir::Place::Local(index) = *place {
3157f602 21 match self.locals[index] {
94b46f34
XL
22 LocalRef::Place(cg_dest) => {
23 self.codegen_rvalue(bx, cg_dest, rvalue)
3157f602 24 }
b7449926
XL
25 LocalRef::UnsizedPlace(cg_indirect_dest) => {
26 self.codegen_rvalue_unsized(bx, cg_indirect_dest, rvalue)
27 }
3157f602 28 LocalRef::Operand(None) => {
94b46f34 29 let (bx, operand) = self.codegen_rvalue_operand(bx, rvalue);
3157f602 30 self.locals[index] = LocalRef::Operand(Some(operand));
2c00a5a8 31 bx
3157f602 32 }
ff7c6d11
XL
33 LocalRef::Operand(Some(op)) => {
34 if !op.layout.is_zst() {
3157f602
XL
35 span_bug!(statement.source_info.span,
36 "operand {:?} already assigned",
37 rvalue);
92a42be0 38 }
ff7c6d11
XL
39
40 // If the type is zero-sized, it's already been set here,
94b46f34
XL
41 // but we still need to make sure we codegen the operand
42 self.codegen_rvalue_operand(bx, rvalue).0
92a42be0
SL
43 }
44 }
3157f602 45 } else {
a1dfa0c6 46 let cg_dest = self.codegen_place(&mut bx, place);
94b46f34 47 self.codegen_rvalue(bx, cg_dest, rvalue)
92a42be0
SL
48 }
49 }
ff7c6d11 50 mir::StatementKind::SetDiscriminant{ref place, variant_index} => {
a1dfa0c6
XL
51 self.codegen_place(&mut bx, place)
52 .codegen_set_discr(&mut bx, variant_index);
2c00a5a8 53 bx
5bcae85e 54 }
ea8adc8c 55 mir::StatementKind::StorageLive(local) => {
94b46f34 56 if let LocalRef::Place(cg_place) = self.locals[local] {
a1dfa0c6 57 cg_place.storage_live(&mut bx);
b7449926 58 } else if let LocalRef::UnsizedPlace(cg_indirect_place) = self.locals[local] {
a1dfa0c6 59 cg_indirect_place.storage_live(&mut bx);
ff7c6d11 60 }
2c00a5a8 61 bx
5bcae85e 62 }
ea8adc8c 63 mir::StatementKind::StorageDead(local) => {
94b46f34 64 if let LocalRef::Place(cg_place) = self.locals[local] {
a1dfa0c6 65 cg_place.storage_dead(&mut bx);
b7449926 66 } else if let LocalRef::UnsizedPlace(cg_indirect_place) = self.locals[local] {
a1dfa0c6 67 cg_indirect_place.storage_dead(&mut bx);
ff7c6d11 68 }
2c00a5a8 69 bx
5bcae85e 70 }
8bb4bdeb
XL
71 mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
72 let outputs = outputs.iter().map(|output| {
a1dfa0c6 73 self.codegen_place(&mut bx, output)
8bb4bdeb
XL
74 }).collect();
75
0bf4aa26 76 let input_vals = inputs.iter()
a1dfa0c6
XL
77 .fold(Vec::with_capacity(inputs.len()), |mut acc, (span, input)| {
78 let op = self.codegen_operand(&mut bx, input);
0bf4aa26
XL
79 if let OperandValue::Immediate(_) = op.val {
80 acc.push(op.immediate());
0bf4aa26 81 } else {
a1dfa0c6
XL
82 span_err!(bx.sess(), span.to_owned(), E0669,
83 "invalid value for constraint in inline assembly");
0bf4aa26 84 }
a1dfa0c6 85 acc
0bf4aa26 86 });
8bb4bdeb 87
a1dfa0c6
XL
88 if input_vals.len() == inputs.len() {
89 let res = bx.codegen_inline_asm(asm, outputs, input_vals);
0bf4aa26
XL
90 if !res {
91 span_err!(bx.sess(), statement.source_info.span, E0668,
92 "malformed inline assembly");
93 }
94 }
2c00a5a8 95 bx
8bb4bdeb 96 }
0bf4aa26 97 mir::StatementKind::FakeRead(..) |
a1dfa0c6 98 mir::StatementKind::Retag { .. } |
b7449926 99 mir::StatementKind::AscribeUserType(..) |
2c00a5a8 100 mir::StatementKind::Nop => bx,
5bcae85e
SL
101 }
102 }
92a42be0 103}