static_inst.hh revision 8809:bb10807da889
111569Sgabor.dozsa@arm.com/*
211348Sandreas.sandberg@arm.com * Copyright (c) 2010 ARM Limited
311348Sandreas.sandberg@arm.com * All rights reserved
411348Sandreas.sandberg@arm.com *
511348Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
611348Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
711348Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
811348Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
911348Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1011348Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1111348Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1211348Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1311348Sandreas.sandberg@arm.com *
1411348Sandreas.sandberg@arm.com * Copyright (c) 2007-2008 The Florida State University
1511348Sandreas.sandberg@arm.com * All rights reserved.
1611348Sandreas.sandberg@arm.com *
1711348Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
1811348Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
1911348Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
2011348Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
2111348Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
2211348Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
2311348Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
2411348Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
2511348Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
2611348Sandreas.sandberg@arm.com * this software without specific prior written permission.
2711348Sandreas.sandberg@arm.com *
2811348Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2911348Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3011348Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3111348Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3211348Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3311348Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3411348Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3513510Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3613510Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3713510Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3813510Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3911348Sandreas.sandberg@arm.com *
4013510Sjairo.balart@metempsy.com * Authors: Stephen Hines
4113510Sjairo.balart@metempsy.com */
4213510Sjairo.balart@metempsy.com#ifndef __ARCH_ARM_INSTS_STATICINST_HH__
4313510Sjairo.balart@metempsy.com#define __ARCH_ARM_INSTS_STATICINST_HH__
4411569Sgabor.dozsa@arm.com
4511569Sgabor.dozsa@arm.com#include "arch/arm/faults.hh"
4613510Sjairo.balart@metempsy.com#include "arch/arm/utility.hh"
4713510Sjairo.balart@metempsy.com#include "base/trace.hh"
4813510Sjairo.balart@metempsy.com#include "cpu/static_inst.hh"
4913510Sjairo.balart@metempsy.com#include "sim/byteswap.hh"
5013510Sjairo.balart@metempsy.com#include "sim/full_system.hh"
5113510Sjairo.balart@metempsy.com
5211348Sandreas.sandberg@arm.comnamespace ArmISA
5311348Sandreas.sandberg@arm.com{
5411348Sandreas.sandberg@arm.com
5511348Sandreas.sandberg@arm.comclass ArmStaticInst : public StaticInst
5611348Sandreas.sandberg@arm.com{
5711348Sandreas.sandberg@arm.com  protected:
5811348Sandreas.sandberg@arm.com    int32_t shift_rm_imm(uint32_t base, uint32_t shamt,
5911348Sandreas.sandberg@arm.com                         uint32_t type, uint32_t cfval) const;
6011348Sandreas.sandberg@arm.com    int32_t shift_rm_rs(uint32_t base, uint32_t shamt,
6111348Sandreas.sandberg@arm.com                        uint32_t type, uint32_t cfval) const;
6212761Sandreas.sandberg@arm.com
6312761Sandreas.sandberg@arm.com    bool shift_carry_imm(uint32_t base, uint32_t shamt,
6413510Sjairo.balart@metempsy.com                         uint32_t type, uint32_t cfval) const;
6513510Sjairo.balart@metempsy.com    bool shift_carry_rs(uint32_t base, uint32_t shamt,
6611348Sandreas.sandberg@arm.com                        uint32_t type, uint32_t cfval) const;
6711348Sandreas.sandberg@arm.com
6811348Sandreas.sandberg@arm.com    template<int width>
6911348Sandreas.sandberg@arm.com    static inline bool
7011348Sandreas.sandberg@arm.com    saturateOp(int32_t &res, int64_t op1, int64_t op2, bool sub=false)
7111348Sandreas.sandberg@arm.com    {
7213510Sjairo.balart@metempsy.com        int64_t midRes = sub ? (op1 - op2) : (op1 + op2);
7313510Sjairo.balart@metempsy.com        if (bits(midRes, width) != bits(midRes, width - 1)) {
7413510Sjairo.balart@metempsy.com            if (midRes > 0)
7511569Sgabor.dozsa@arm.com                res = (LL(1) << (width - 1)) - 1;
7611569Sgabor.dozsa@arm.com            else
7711569Sgabor.dozsa@arm.com                res = -(LL(1) << (width - 1));
7811569Sgabor.dozsa@arm.com            return true;
7911348Sandreas.sandberg@arm.com        } else {
8011348Sandreas.sandberg@arm.com            res = midRes;
8111348Sandreas.sandberg@arm.com            return false;
8211348Sandreas.sandberg@arm.com        }
8311348Sandreas.sandberg@arm.com    }
8411348Sandreas.sandberg@arm.com
8511348Sandreas.sandberg@arm.com    static inline bool
86    satInt(int32_t &res, int64_t op, int width)
87    {
88        width--;
89        if (op >= (LL(1) << width)) {
90            res = (LL(1) << width) - 1;
91            return true;
92        } else if (op < -(LL(1) << width)) {
93            res = -(LL(1) << width);
94            return true;
95        } else {
96            res = op;
97            return false;
98        }
99    }
100
101    template<int width>
102    static inline bool
103    uSaturateOp(uint32_t &res, int64_t op1, int64_t op2, bool sub=false)
104    {
105        int64_t midRes = sub ? (op1 - op2) : (op1 + op2);
106        if (midRes >= (LL(1) << width)) {
107            res = (LL(1) << width) - 1;
108            return true;
109        } else if (midRes < 0) {
110            res = 0;
111            return true;
112        } else {
113            res = midRes;
114            return false;
115        }
116    }
117
118    static inline bool
119    uSatInt(int32_t &res, int64_t op, int width)
120    {
121        if (op >= (LL(1) << width)) {
122            res = (LL(1) << width) - 1;
123            return true;
124        } else if (op < 0) {
125            res = 0;
126            return true;
127        } else {
128            res = op;
129            return false;
130        }
131    }
132
133    // Constructor
134    ArmStaticInst(const char *mnem, ExtMachInst _machInst,
135                  OpClass __opClass)
136        : StaticInst(mnem, _machInst, __opClass)
137    {
138    }
139
140    /// Print a register name for disassembly given the unique
141    /// dependence tag number (FP or int).
142    void printReg(std::ostream &os, int reg) const;
143    void printMnemonic(std::ostream &os,
144                       const std::string &suffix = "",
145                       bool withPred = true) const;
146    void printMemSymbol(std::ostream &os, const SymbolTable *symtab,
147                        const std::string &prefix, const Addr addr,
148                        const std::string &suffix) const;
149    void printShiftOperand(std::ostream &os, IntRegIndex rm,
150                           bool immShift, uint32_t shiftAmt,
151                           IntRegIndex rs, ArmShiftType type) const;
152
153
154    void printDataInst(std::ostream &os, bool withImm) const;
155    void printDataInst(std::ostream &os, bool withImm, bool immShift, bool s,
156                       IntRegIndex rd, IntRegIndex rn, IntRegIndex rm,
157                       IntRegIndex rs, uint32_t shiftAmt, ArmShiftType type,
158                       uint32_t imm) const;
159
160    void
161    advancePC(PCState &pcState) const
162    {
163        pcState.advance();
164    }
165
166    std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
167
168    static inline uint32_t
169    cpsrWriteByInstr(CPSR cpsr, uint32_t val,
170            uint8_t byteMask, bool affectState, bool nmfi)
171    {
172        bool privileged = (cpsr.mode != MODE_USER);
173
174        uint32_t bitMask = 0;
175
176        if (bits(byteMask, 3)) {
177            unsigned lowIdx = affectState ? 24 : 27;
178            bitMask = bitMask | mask(31, lowIdx);
179        }
180        if (bits(byteMask, 2)) {
181            bitMask = bitMask | mask(19, 16);
182        }
183        if (bits(byteMask, 1)) {
184            unsigned highIdx = affectState ? 15 : 9;
185            unsigned lowIdx = privileged ? 8 : 9;
186            bitMask = bitMask | mask(highIdx, lowIdx);
187        }
188        if (bits(byteMask, 0)) {
189            if (privileged) {
190                bitMask = bitMask | mask(7, 6);
191                if (!badMode((OperatingMode)(val & mask(5)))) {
192                    bitMask = bitMask | mask(5);
193                } else {
194                    warn_once("Ignoring write of bad mode to CPSR.\n");
195                }
196            }
197            if (affectState)
198                bitMask = bitMask | (1 << 5);
199        }
200
201        bool cpsr_f = cpsr.f;
202        uint32_t new_cpsr = ((uint32_t)cpsr & ~bitMask) | (val & bitMask);
203        if (nmfi && !cpsr_f)
204            new_cpsr &= ~(1 << 6);
205        return new_cpsr;
206    }
207
208    static inline uint32_t
209    spsrWriteByInstr(uint32_t spsr, uint32_t val,
210            uint8_t byteMask, bool affectState)
211    {
212        uint32_t bitMask = 0;
213
214        if (bits(byteMask, 3))
215            bitMask = bitMask | mask(31, 24);
216        if (bits(byteMask, 2))
217            bitMask = bitMask | mask(19, 16);
218        if (bits(byteMask, 1))
219            bitMask = bitMask | mask(15, 8);
220        if (bits(byteMask, 0))
221            bitMask = bitMask | mask(7, 0);
222
223        return ((spsr & ~bitMask) | (val & bitMask));
224    }
225
226    template<class XC>
227    static inline Addr
228    readPC(XC *xc)
229    {
230        return xc->pcState().instPC();
231    }
232
233    template<class XC>
234    static inline void
235    setNextPC(XC *xc, Addr val)
236    {
237        PCState pc = xc->pcState();
238        pc.instNPC(val);
239        xc->pcState(pc);
240    }
241
242    template<class T>
243    static inline T
244    cSwap(T val, bool big)
245    {
246        if (big) {
247            return gtobe(val);
248        } else {
249            return gtole(val);
250        }
251    }
252
253    template<class T, class E>
254    static inline T
255    cSwap(T val, bool big)
256    {
257        const unsigned count = sizeof(T) / sizeof(E);
258        union {
259            T tVal;
260            E eVals[count];
261        } conv;
262        conv.tVal = htog(val);
263        if (big) {
264            for (unsigned i = 0; i < count; i++) {
265                conv.eVals[i] = gtobe(conv.eVals[i]);
266            }
267        } else {
268            for (unsigned i = 0; i < count; i++) {
269                conv.eVals[i] = gtole(conv.eVals[i]);
270            }
271        }
272        return gtoh(conv.tVal);
273    }
274
275    // Perform an interworking branch.
276    template<class XC>
277    static inline void
278    setIWNextPC(XC *xc, Addr val)
279    {
280        PCState pc = xc->pcState();
281        pc.instIWNPC(val);
282        xc->pcState(pc);
283    }
284
285    // Perform an interworking branch in ARM mode, a regular branch
286    // otherwise.
287    template<class XC>
288    static inline void
289    setAIWNextPC(XC *xc, Addr val)
290    {
291        PCState pc = xc->pcState();
292        pc.instAIWNPC(val);
293        xc->pcState(pc);
294    }
295
296    inline Fault
297    disabledFault() const
298    {
299        if (FullSystem) {
300            return new UndefinedInstruction();
301        } else {
302            return new UndefinedInstruction(machInst, false, mnemonic, true);
303        }
304    }
305};
306}
307
308#endif //__ARCH_ARM_INSTS_STATICINST_HH__
309