diff options
| author | Antoni Boucher <bouanto@zoho.com> | 2021-08-15 08:29:07 -0400 |
|---|---|---|
| committer | Antoni Boucher <bouanto@zoho.com> | 2021-08-15 08:29:07 -0400 |
| commit | 3d5d4e324d683ad5519345089d4a1ecb3c3d1f42 (patch) | |
| tree | 0859c94db30cb4e9b5c5a4341d7ebf6580fdf7f1 /compiler/rustc_codegen_gcc/src/asm.rs | |
| parent | 6fc069625a32c0a2ff79075eac3d784268fd9882 (diff) | |
| parent | e228f0c16ea8c34794a6285bf57aab627c26b147 (diff) | |
| download | rust-3d5d4e324d683ad5519345089d4a1ecb3c3d1f42.tar.gz rust-3d5d4e324d683ad5519345089d4a1ecb3c3d1f42.zip | |
Merge commit 'e228f0c16ea8c34794a6285bf57aab627c26b147' into libgccjit-codegen
Diffstat (limited to 'compiler/rustc_codegen_gcc/src/asm.rs')
| -rw-r--r-- | compiler/rustc_codegen_gcc/src/asm.rs | 200 |
1 files changed, 12 insertions, 188 deletions
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index 6616366235f..e4d57c39de4 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -15,106 +15,8 @@ use crate::type_of::LayoutGccExt; impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { fn codegen_llvm_inline_asm(&mut self, _ia: &LlvmInlineAsmInner, _outputs: Vec<PlaceRef<'tcx, RValue<'gcc>>>, mut _inputs: Vec<RValue<'gcc>>, _span: Span) -> bool { - // TODO + // TODO(antoyo) return true; - - /*let mut ext_constraints = vec![]; - let mut output_types = vec![]; - - // Prepare the output operands - let mut indirect_outputs = vec![]; - for (i, (out, &place)) in ia.outputs.iter().zip(&outputs).enumerate() { - if out.is_rw { - let operand = self.load_operand(place); - if let OperandValue::Immediate(_) = operand.val { - inputs.push(operand.immediate()); - } - ext_constraints.push(i.to_string()); - } - if out.is_indirect { - let operand = self.load_operand(place); - if let OperandValue::Immediate(_) = operand.val { - indirect_outputs.push(operand.immediate()); - } - } else { - output_types.push(place.layout.gcc_type(self.cx())); - } - } - if !indirect_outputs.is_empty() { - indirect_outputs.extend_from_slice(&inputs); - inputs = indirect_outputs; - } - - let clobbers = ia.clobbers.iter().map(|s| format!("~{{{}}}", &s)); - - // Default per-arch clobbers - // Basically what clang does - let arch_clobbers = match &self.sess().target.target.arch[..] { - "x86" | "x86_64" => vec!["~{dirflag}", "~{fpsr}", "~{flags}"], - "mips" | "mips64" => vec!["~{$1}"], - _ => Vec::new(), - }; - - let all_constraints = ia - .outputs - .iter() - .map(|out| out.constraint.to_string()) - .chain(ia.inputs.iter().map(|s| s.to_string())) - .chain(ext_constraints) - .chain(clobbers) - .chain(arch_clobbers.iter().map(|s| (*s).to_string())) - .collect::<Vec<String>>() - .join(","); - - debug!("Asm Constraints: {}", &all_constraints); - - // Depending on how many outputs we have, the return type is different - let num_outputs = output_types.len(); - let output_type = match num_outputs { - 0 => self.type_void(), - 1 => output_types[0], - _ => self.type_struct(&output_types, false), - }; - - let asm = ia.asm.as_str(); - let r = inline_asm_call( - self, - &asm, - &all_constraints, - &inputs, - output_type, - ia.volatile, - ia.alignstack, - ia.dialect, - ); - if r.is_none() { - return false; - } - let r = r.unwrap(); - - // Again, based on how many outputs we have - let outputs = ia.outputs.iter().zip(&outputs).filter(|&(ref o, _)| !o.is_indirect); - for (i, (_, &place)) in outputs.enumerate() { - let v = if num_outputs == 1 { r } else { self.extract_value(r, i as u64) }; - OperandValue::Immediate(v).store(self, place); - } - - // Store mark in a metadata node so we can map LLVM errors - // back to source locations. See #17552. - unsafe { - let key = "srcloc"; - let kind = llvm::LLVMGetMDKindIDInContext( - self.llcx, - key.as_ptr() as *const c_char, - key.len() as c_uint, - ); - - let val: &'ll Value = self.const_i32(span.ctxt().outer_expn().as_u32() as i32); - - llvm::LLVMSetMetadata(r, kind, llvm::LLVMMDNodeInContext(self.llcx, &val, 1)); - } - - true*/ } fn codegen_inline_asm(&mut self, template: &[InlineAsmTemplatePiece], operands: &[InlineAsmOperandRef<'tcx, Self>], options: InlineAsmOptions, _span: &[Span]) { @@ -127,7 +29,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { }; // Collect the types of output operands - // FIXME: we do this here instead of later because of a bug in libgccjit where creating the + // FIXME(antoyo): we do this here instead of later because of a bug in libgccjit where creating the // variable after the extended asm expression causes a segfault: // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100380 let mut output_vars = FxHashMap::default(); @@ -160,11 +62,6 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { match out_place { Some(place) => place.layout.gcc_type(self.cx, false), None => { - // If the output is discarded, we don't really care what - // type is used. We're just using this to tell GCC to - // reserve the register. - //dummy_output_type(self.cx, reg.reg_class()) - // NOTE: if no output value, we should not create one. continue; }, @@ -251,9 +148,9 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { template_str } else { - // FIXME: this might break the "m" memory constraint: + // FIXME(antoyo): this might break the "m" memory constraint: // https://stackoverflow.com/a/9347957/389119 - // TODO: only set on x86 platforms. + // TODO(antoyo): only set on x86 platforms. format!(".att_syntax noprefix\n\t{}\n\t.intel_syntax noprefix", template_str) }; let extended_asm = block.add_extended_asm(None, &template_str); @@ -274,7 +171,6 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { }, }; output_types.push(ty); - //op_idx.insert(idx, constraints.len()); let prefix = if late { "=" } else { "=&" }; let constraint = format!("{}{}", prefix, reg_to_gcc(reg)); @@ -295,14 +191,13 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { None => dummy_output_type(self.cx, reg.reg_class()) }; output_types.push(ty); - //op_idx.insert(idx, constraints.len()); - // TODO: prefix of "+" for reading and writing? + // TODO(antoyo): prefix of "+" for reading and writing? let prefix = if late { "=" } else { "=&" }; let constraint = format!("{}{}", prefix, reg_to_gcc(reg)); if out_place.is_some() { let var = output_vars[&idx]; - // TODO: also specify an output operand when out_place is none: that would + // TODO(antoyo): also specify an output operand when out_place is none: that would // be the clobber but clobbers do not support general constraint like reg; // they only support named registers. // Not sure how we can do this. And the LLVM backend does not seem to add a @@ -321,63 +216,6 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } } - /*if !options.contains(InlineAsmOptions::PRESERVES_FLAGS) { - match asm_arch { - InlineAsmArch::AArch64 | InlineAsmArch::Arm => { - constraints.push("~{cc}".to_string()); - } - InlineAsmArch::X86 | InlineAsmArch::X86_64 => { - constraints.extend_from_slice(&[ - "~{dirflag}".to_string(), - "~{fpsr}".to_string(), - "~{flags}".to_string(), - ]); - } - InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {} - } - } - if !options.contains(InlineAsmOptions::NOMEM) { - // This is actually ignored by LLVM, but it's probably best to keep - // it just in case. LLVM instead uses the ReadOnly/ReadNone - // attributes on the call instruction to optimize. - constraints.push("~{memory}".to_string()); - } - let volatile = !options.contains(InlineAsmOptions::PURE); - let alignstack = !options.contains(InlineAsmOptions::NOSTACK); - let output_type = match &output_types[..] { - [] => self.type_void(), - [ty] => ty, - tys => self.type_struct(&tys, false), - };*/ - - /*let result = inline_asm_call( - self, - &template_str, - &constraints.join(","), - &inputs, - output_type, - volatile, - alignstack, - dialect, - span, - ) - .unwrap_or_else(|| span_bug!(span, "LLVM asm constraint validation failed")); - - if options.contains(InlineAsmOptions::PURE) { - if options.contains(InlineAsmOptions::NOMEM) { - llvm::Attribute::ReadNone.apply_callsite(llvm::AttributePlace::Function, result); - } else if options.contains(InlineAsmOptions::READONLY) { - llvm::Attribute::ReadOnly.apply_callsite(llvm::AttributePlace::Function, result); - } - } else { - if options.contains(InlineAsmOptions::NOMEM) { - llvm::Attribute::InaccessibleMemOnly - .apply_callsite(llvm::AttributePlace::Function, result); - } else { - // LLVM doesn't have an attribute to represent ReadOnly + SideEffect - } - }*/ - // Write results to outputs for (idx, op) in operands.iter().enumerate() { if let InlineAsmOperandRef::Out { place: Some(place), .. } @@ -390,12 +228,12 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } /// Converts a register class to a GCC constraint code. -// TODO: return &'static str instead? +// TODO(antoyo): return &'static str instead? fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> String { match reg { // For vector registers LLVM wants the register name to match the type size. InlineAsmRegOrRegClass::Reg(reg) => { - // TODO: add support for vector register. + // TODO(antoyo): add support for vector register. let constraint = match reg.name() { "ax" => "a", @@ -404,11 +242,11 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> String { "dx" => "d", "si" => "S", "di" => "D", - // TODO: for registers like r11, we have to create a register variable: https://stackoverflow.com/a/31774784/389119 - // TODO: in this case though, it's a clobber, so it should work as r11. + // TODO(antoyo): for registers like r11, we have to create a register variable: https://stackoverflow.com/a/31774784/389119 + // TODO(antoyo): in this case though, it's a clobber, so it should work as r11. // Recent nightly supports clobber() syntax, so update to it. It does not seem // like it's implemented yet. - name => name, // FIXME: probably wrong. + name => name, // FIXME(antoyo): probably wrong. }; constraint.to_string() }, @@ -570,7 +408,6 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) | InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => { unimplemented!() - //if modifier == Some('v') { None } else { modifier } } InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => unimplemented!(), @@ -583,11 +420,6 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low4) => { unimplemented!() - /*if modifier.is_none() { - Some('q') - } else { - modifier - }*/ } InlineAsmRegClass::Bpf(_) => unimplemented!(), InlineAsmRegClass::Hexagon(_) => unimplemented!(), @@ -612,15 +444,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_byte) => unimplemented!(), InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg) | InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) - | InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => unimplemented!() /*match (reg, modifier) { - (X86InlineAsmRegClass::xmm_reg, None) => Some('x'), - (X86InlineAsmRegClass::ymm_reg, None) => Some('t'), - (X86InlineAsmRegClass::zmm_reg, None) => Some('g'), - (_, Some('x')) => Some('x'), - (_, Some('y')) => Some('t'), - (_, Some('z')) => Some('g'), - _ => unreachable!(), - }*/, + | InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => unimplemented!(), InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg) => unimplemented!(), InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => unimplemented!(), InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => unimplemented!(), |
