]> git.lizzy.rs Git - rust.git/commitdiff
Handle argument extension mode
authorbjorn3 <bjorn3@users.noreply.github.com>
Sat, 30 Jan 2021 11:25:20 +0000 (12:25 +0100)
committerbjorn3 <bjorn3@users.noreply.github.com>
Sat, 30 Jan 2021 11:25:20 +0000 (12:25 +0100)
src/abi/pass_mode.rs

index b3231e94a33b99fb13d0a3e0d935c2f4ca0e5ac4..2f91e83386ceb7fb15291e58abec9f20ff8afe25 100644 (file)
@@ -3,8 +3,10 @@
 use crate::prelude::*;
 use crate::value_and_place::assert_assignable;
 
-use cranelift_codegen::ir::ArgumentPurpose;
-use rustc_target::abi::call::{ArgAbi, CastTarget, PassMode, Reg, RegKind};
+use cranelift_codegen::ir::{ArgumentExtension, ArgumentPurpose};
+use rustc_target::abi::call::{
+    ArgAbi, ArgAttributes, ArgExtension as RustcArgExtension, CastTarget, PassMode, Reg, RegKind,
+};
 use smallvec::{smallvec, SmallVec};
 
 pub(super) trait ArgAbiExt<'tcx> {
@@ -27,6 +29,15 @@ fn reg_to_abi_param(reg: Reg) -> AbiParam {
     AbiParam::new(clif_ty)
 }
 
+fn apply_arg_attrs_to_abi_param(mut param: AbiParam, arg_attrs: ArgAttributes) -> AbiParam {
+    match arg_attrs.arg_ext {
+        RustcArgExtension::None => {}
+        RustcArgExtension::Zext => param.extension = ArgumentExtension::Uext,
+        RustcArgExtension::Sext => param.extension = ArgumentExtension::Sext,
+    }
+    param
+}
+
 fn cast_target_to_abi_params(cast: CastTarget) -> SmallVec<[AbiParam; 2]> {
     let (rest_count, rem_bytes) = if cast.rest.unit.size.bytes() == 0 {
         (0, 0)
@@ -82,15 +93,16 @@ fn reg_to_abi_param(reg: Reg) -> AbiParam {
     args
 }
 
-// FIXME respect argument extension mode
-
 impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
     fn get_abi_param(&self, tcx: TyCtxt<'tcx>) -> SmallVec<[AbiParam; 2]> {
         match self.mode {
             PassMode::Ignore => smallvec![],
-            PassMode::Direct(_) => match &self.layout.abi {
+            PassMode::Direct(attrs) => match &self.layout.abi {
                 Abi::Scalar(scalar) => {
-                    smallvec![AbiParam::new(scalar_to_clif_type(tcx, scalar.clone()))]
+                    smallvec![apply_arg_attrs_to_abi_param(
+                        AbiParam::new(scalar_to_clif_type(tcx, scalar.clone())),
+                        attrs
+                    )]
                 }
                 Abi::Vector { .. } => {
                     let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout).unwrap();
@@ -98,39 +110,45 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
                 }
                 _ => unreachable!("{:?}", self.layout.abi),
             },
-            PassMode::Pair(_, _) => match &self.layout.abi {
+            PassMode::Pair(attrs_a, attrs_b) => match &self.layout.abi {
                 Abi::ScalarPair(a, b) => {
                     let a = scalar_to_clif_type(tcx, a.clone());
                     let b = scalar_to_clif_type(tcx, b.clone());
-                    smallvec![AbiParam::new(a), AbiParam::new(b)]
+                    smallvec![
+                        apply_arg_attrs_to_abi_param(AbiParam::new(a), attrs_a),
+                        apply_arg_attrs_to_abi_param(AbiParam::new(b), attrs_b),
+                    ]
                 }
                 _ => unreachable!("{:?}", self.layout.abi),
             },
             PassMode::Cast(cast) => cast_target_to_abi_params(cast),
             PassMode::Indirect {
-                attrs: _,
+                attrs,
                 extra_attrs: None,
                 on_stack,
             } => {
                 if on_stack {
                     let size = u32::try_from(self.layout.size.bytes()).unwrap();
-                    smallvec![AbiParam::special(
-                        pointer_ty(tcx),
-                        ArgumentPurpose::StructArgument(size),
+                    smallvec![apply_arg_attrs_to_abi_param(
+                        AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructArgument(size),),
+                        attrs
                     )]
                 } else {
-                    smallvec![AbiParam::new(pointer_ty(tcx))]
+                    smallvec![apply_arg_attrs_to_abi_param(
+                        AbiParam::new(pointer_ty(tcx)),
+                        attrs
+                    )]
                 }
             }
             PassMode::Indirect {
-                attrs: _,
-                extra_attrs: Some(_),
+                attrs,
+                extra_attrs: Some(extra_attrs),
                 on_stack,
             } => {
                 assert!(!on_stack);
                 smallvec![
-                    AbiParam::new(pointer_ty(tcx)),
-                    AbiParam::new(pointer_ty(tcx)),
+                    apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs),
+                    apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), extra_attrs),
                 ]
             }
         }