12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
16b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
17166db04e259ca51838c311891598664deeed85adIan Rogers#ifndef ART_COMPILER_UTILS_MANAGED_REGISTER_H_
18166db04e259ca51838c311891598664deeed85adIan Rogers#define ART_COMPILER_UTILS_MANAGED_REGISTER_H_
19b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
20fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko#include <vector>
21fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace art {
232c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace arm {
252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersclass ArmManagedRegister;
262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers}
27ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescunamespace arm64 {
28ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescuclass Arm64ManagedRegister;
29ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu}
307fbee0731b14b5bf392a4254f5cd84685ab517dajeffhaonamespace mips {
317fbee0731b14b5bf392a4254f5cd84685ab517dajeffhaoclass MipsManagedRegister;
327fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao}
3357b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampenamespace mips64 {
3457b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampeclass Mips64ManagedRegister;
3557b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe}
36fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
377fbee0731b14b5bf392a4254f5cd84685ab517dajeffhaonamespace x86 {
387fbee0731b14b5bf392a4254f5cd84685ab517dajeffhaoclass X86ManagedRegister;
397fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao}
402c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
41fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkonamespace x86_64 {
42fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkoclass X86_64ManagedRegister;
43fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko}
44fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
452c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersclass ManagedRegister {
462c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers public:
472c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  // ManagedRegister is a value class. There exists no method to change the
482c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  // internal state. We therefore allow a copy constructor and an
492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  // assignment-operator.
502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ManagedRegister(const ManagedRegister& other) : id_(other.id_) { }
512c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
522c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ManagedRegister& operator=(const ManagedRegister& other) {
532c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    id_ = other.id_;
542c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    return *this;
552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  }
562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  arm::ArmManagedRegister AsArm() const;
58ed8dd492e43cbaaa435c4892447072c84dbaf2dcSerban Constantinescu  arm64::Arm64ManagedRegister AsArm64() const;
597fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  mips::MipsManagedRegister AsMips() const;
6057b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe  mips64::Mips64ManagedRegister AsMips64() const;
617fbee0731b14b5bf392a4254f5cd84685ab517dajeffhao  x86::X86ManagedRegister AsX86() const;
62fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  x86_64::X86_64ManagedRegister AsX86_64() const;
632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  // It is valid to invoke Equals on and with a NoRegister.
652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  bool Equals(const ManagedRegister& other) const {
662c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    return id_ == other.id_;
672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  }
682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
692c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  bool IsNoRegister() const {
702c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    return id_ == kNoRegister;
712c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  }
722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  static ManagedRegister NoRegister() {
742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    return ManagedRegister();
752c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  }
762c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
7701bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  int RegId() const { return id_; }
7801bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  explicit ManagedRegister(int reg_id) : id_(reg_id) { }
7901bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray
802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers protected:
812c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  static const int kNoRegister = -1;
822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
832c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ManagedRegister() : id_(kNoRegister) { }
842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  int id_;
862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers};
872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
88fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkoclass ManagedRegisterSpill : public ManagedRegister {
89fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko public:
90fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // ManagedRegisterSpill contains information about data type size and location in caller frame
91fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // These additional attributes could be defined by calling convention (EntrySpills)
92fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  ManagedRegisterSpill(const ManagedRegister& other, uint32_t size, uint32_t spill_offset)
93fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      : ManagedRegister(other), size_(size), spill_offset_(spill_offset)  { }
94fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
95fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  explicit ManagedRegisterSpill(const ManagedRegister& other)
96fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko      : ManagedRegister(other), size_(-1), spill_offset_(-1) { }
97fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
9875b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu  explicit ManagedRegisterSpill(const ManagedRegister& other, int32_t size)
9975b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu      : ManagedRegister(other), size_(size), spill_offset_(-1) { }
10075b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu
101fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int32_t getSpillOffset() {
102fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    return spill_offset_;
103fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
104fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
105fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int32_t getSize() {
106fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    return size_;
107fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
108fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
109fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko private:
110fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int32_t size_;
111fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  int32_t spill_offset_;
112fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko};
113fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
114fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenkoclass ManagedRegisterEntrySpills : public std::vector<ManagedRegisterSpill> {
115fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko public:
116fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // The ManagedRegister does not have information about size and offset.
117fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  // In this case it's size and offset determined by BuildFrame (assembler)
118fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  void push_back(ManagedRegister __x) {
119fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    ManagedRegisterSpill spill(__x);
120fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    std::vector<ManagedRegisterSpill>::push_back(spill);
121fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
122fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
12375b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu  void push_back(ManagedRegister __x, int32_t __size) {
12475b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu    ManagedRegisterSpill spill(__x, __size);
12575b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu    std::vector<ManagedRegisterSpill>::push_back(spill);
12675b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu  }
12775b9113b2b0a5807043af2a669a93d1579af8e2cSerban Constantinescu
128fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  void push_back(ManagedRegisterSpill __x) {
129fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko    std::vector<ManagedRegisterSpill>::push_back(__x);
130fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko  }
131fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko private:
132fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko};
133fca82208f7128fcda09b6a4743199308332558a2Dmitry Petrochenko
1342c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers}  // namespace art
135b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
136166db04e259ca51838c311891598664deeed85adIan Rogers#endif  // ART_COMPILER_UTILS_MANAGED_REGISTER_H_
137