@@ -57,19 +57,28 @@ mod attr_impl {
5757 const NoCapture = 1 << 2 ;
5858 const NonNull = 1 << 3 ;
5959 const ReadOnly = 1 << 4 ;
60- const SExt = 1 << 5 ;
6160 const StructRet = 1 << 6 ;
62- const ZExt = 1 << 7 ;
6361 const InReg = 1 << 8 ;
6462 }
6563 }
6664}
6765
66+ /// Sometimes an ABI requires small integers to be extended to a full or partial register. This enum
67+ /// defines if this extension should be zero-extension or sign-extension when necssary. When it is
68+ /// not necesary to extend the argument, this enum is ignored.
69+ #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
70+ pub enum ArgExtension {
71+ None ,
72+ Zext ,
73+ Sext ,
74+ }
75+
6876/// A compact representation of LLVM attributes (at least those relevant for this module)
6977/// that can be manipulated without interacting with LLVM's Attribute machinery.
7078#[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
7179pub struct ArgAttributes {
7280 pub regular : ArgAttribute ,
81+ pub arg_ext : ArgExtension ,
7382 /// The minimum size of the pointee, guaranteed to be valid for the duration of the whole call
7483 /// (corresponding to LLVM's dereferenceable and dereferenceable_or_null attributes).
7584 pub pointee_size : Size ,
@@ -80,11 +89,24 @@ impl ArgAttributes {
8089 pub fn new ( ) -> Self {
8190 ArgAttributes {
8291 regular : ArgAttribute :: default ( ) ,
92+ arg_ext : ArgExtension :: None ,
8393 pointee_size : Size :: ZERO ,
8494 pointee_align : None ,
8595 }
8696 }
8797
98+ pub fn zext ( & mut self ) -> & mut Self {
99+ assert_ne ! ( self . arg_ext, ArgExtension :: Sext ) ;
100+ self . arg_ext = ArgExtension :: Zext ;
101+ self
102+ }
103+
104+ pub fn sext ( & mut self ) -> & mut Self {
105+ assert_ne ! ( self . arg_ext, ArgExtension :: Zext ) ;
106+ self . arg_ext = ArgExtension :: Sext ;
107+ self
108+ }
109+
88110 pub fn set ( & mut self , attr : ArgAttribute ) -> & mut Self {
89111 self . regular |= attr;
90112 self
@@ -457,7 +479,11 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
457479 if let abi:: Int ( i, signed) = scalar. value {
458480 if i. size ( ) . bits ( ) < bits {
459481 if let PassMode :: Direct ( ref mut attrs) = self . mode {
460- attrs. set ( if signed { ArgAttribute :: SExt } else { ArgAttribute :: ZExt } ) ;
482+ if signed {
483+ attrs. sext ( )
484+ } else {
485+ attrs. zext ( )
486+ } ;
461487 }
462488 }
463489 }
0 commit comments