summaryrefslogtreecommitdiff
path: root/include/llvm/Target/TargetCallingConv.h
blob: a6251e7d3345d39f72f9547394827d4c2a98ba89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//===-- llvm/Target/TargetCallingConv.h - Calling Convention ----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines types for working with calling-convention information.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TARGET_TARGETCALLINGCONV_H
#define LLVM_TARGET_TARGETCALLINGCONV_H

#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
#include <string>

namespace llvm {

namespace ISD {
  struct ArgFlagsTy {
  private:
    static const uint64_t NoFlagSet      = 0ULL;
    static const uint64_t ZExt           = 1ULL<<0;  ///< Zero extended
    static const uint64_t ZExtOffs       = 0;
    static const uint64_t SExt           = 1ULL<<1;  ///< Sign extended
    static const uint64_t SExtOffs       = 1;
    static const uint64_t InReg          = 1ULL<<2;  ///< Passed in register
    static const uint64_t InRegOffs      = 2;
    static const uint64_t SRet           = 1ULL<<3;  ///< Hidden struct-ret ptr
    static const uint64_t SRetOffs       = 3;
    static const uint64_t ByVal          = 1ULL<<4;  ///< Struct passed by value
    static const uint64_t ByValOffs      = 4;
    static const uint64_t Nest           = 1ULL<<5;  ///< Nested fn static chain
    static const uint64_t NestOffs       = 5;
    static const uint64_t ByValAlign     = 0xFULL << 6; //< Struct alignment
    static const uint64_t ByValAlignOffs = 6;
    static const uint64_t Split          = 1ULL << 10;
    static const uint64_t SplitOffs      = 10;
    static const uint64_t OrigAlign      = 0x1FULL<<27;
    static const uint64_t OrigAlignOffs  = 27;
    static const uint64_t ByValSize      = 0xffffffffULL << 32; //< Struct size
    static const uint64_t ByValSizeOffs  = 32;

    static const uint64_t One            = 1ULL; //< 1 of this type, for shifts

    uint64_t Flags;
  public:
    ArgFlagsTy() : Flags(0) { }

    bool isZExt()   const { return Flags & ZExt; }
    void setZExt()  { Flags |= One << ZExtOffs; }

    bool isSExt()   const { return Flags & SExt; }
    void setSExt()  { Flags |= One << SExtOffs; }

    bool isInReg()  const { return Flags & InReg; }
    void setInReg() { Flags |= One << InRegOffs; }

    bool isSRet()   const { return Flags & SRet; }
    void setSRet()  { Flags |= One << SRetOffs; }

    bool isByVal()  const { return Flags & ByVal; }
    void setByVal() { Flags |= One << ByValOffs; }

    bool isNest()   const { return Flags & Nest; }
    void setNest()  { Flags |= One << NestOffs; }

    unsigned getByValAlign() const {
      return (unsigned)
        ((One << ((Flags & ByValAlign) >> ByValAlignOffs)) / 2);
    }
    void setByValAlign(unsigned A) {
      Flags = (Flags & ~ByValAlign) |
        (uint64_t(Log2_32(A) + 1) << ByValAlignOffs);
    }

    bool isSplit()   const { return Flags & Split; }
    void setSplit()  { Flags |= One << SplitOffs; }

    unsigned getOrigAlign() const {
      return (unsigned)
        ((One << ((Flags & OrigAlign) >> OrigAlignOffs)) / 2);
    }
    void setOrigAlign(unsigned A) {
      Flags = (Flags & ~OrigAlign) |
        (uint64_t(Log2_32(A) + 1) << OrigAlignOffs);
    }

    unsigned getByValSize() const {
      return (unsigned)((Flags & ByValSize) >> ByValSizeOffs);
    }
    void setByValSize(unsigned S) {
      Flags = (Flags & ~ByValSize) | (uint64_t(S) << ByValSizeOffs);
    }

    /// getArgFlagsString - Returns the flags as a string, eg: "zext align:4".
    std::string getArgFlagsString();

    /// getRawBits - Represent the flags as a bunch of bits.
    uint64_t getRawBits() const { return Flags; }
  };

  /// InputArg - This struct carries flags and type information about a
  /// single incoming (formal) argument or incoming (from the perspective
  /// of the caller) return value virtual register.
  ///
  struct InputArg {
    ArgFlagsTy Flags;
    MVT VT;
    bool Used;

    InputArg() : VT(MVT::Other), Used(false) {}
    InputArg(ArgFlagsTy flags, EVT vt, bool used)
      : Flags(flags), Used(used) {
      VT = vt.getSimpleVT();
    }
  };

  /// OutputArg - This struct carries flags and a value for a
  /// single outgoing (actual) argument or outgoing (from the perspective
  /// of the caller) return value virtual register.
  ///
  struct OutputArg {
    ArgFlagsTy Flags;
    MVT VT;

    /// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
    bool IsFixed;

    OutputArg() : IsFixed(false) {}
    OutputArg(ArgFlagsTy flags, EVT vt, bool isfixed)
      : Flags(flags), IsFixed(isfixed) {
      VT = vt.getSimpleVT();
    }
  };
}

} // end llvm namespace

#endif