pal.isa revision 2632:1bb2f91485ea
1// -*- mode:c++ -*-
2
3// Copyright (c) 2003-2005 The Regents of The University of Michigan
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29output header {{
30    /**
31     * Base class for emulated call_pal calls (used only in
32     * non-full-system mode).
33     */
34    class EmulatedCallPal : public AlphaStaticInst
35    {
36      protected:
37
38        /// Constructor.
39        EmulatedCallPal(const char *mnem, ExtMachInst _machInst,
40                        OpClass __opClass)
41            : AlphaStaticInst(mnem, _machInst, __opClass)
42        {
43        }
44
45        std::string
46        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
47    };
48}};
49
50output decoder {{
51    std::string
52    EmulatedCallPal::generateDisassembly(Addr pc,
53                                         const SymbolTable *symtab) const
54    {
55#ifdef SS_COMPATIBLE_DISASSEMBLY
56        return csprintf("%s %s", "call_pal", mnemonic);
57#else
58        return csprintf("%-10s %s", "call_pal", mnemonic);
59#endif
60    }
61}};
62
63def format EmulatedCallPal(code, *flags) {{
64    iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags)
65    header_output = BasicDeclare.subst(iop)
66    decoder_output = BasicConstructor.subst(iop)
67    decode_block = BasicDecode.subst(iop)
68    exec_output = BasicExecute.subst(iop)
69}};
70
71output header {{
72    /**
73     * Base class for full-system-mode call_pal instructions.
74     * Probably could turn this into a leaf class and get rid of the
75     * parser template.
76     */
77    class CallPalBase : public AlphaStaticInst
78    {
79      protected:
80        int palFunc;	///< Function code part of instruction
81        int palOffset;	///< Target PC, offset from IPR_PAL_BASE
82        bool palValid;	///< is the function code valid?
83        bool palPriv;	///< is this call privileged?
84
85        /// Constructor.
86        CallPalBase(const char *mnem, ExtMachInst _machInst,
87                    OpClass __opClass);
88
89        std::string
90        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
91    };
92}};
93
94output decoder {{
95    inline
96    CallPalBase::CallPalBase(const char *mnem, ExtMachInst _machInst,
97                             OpClass __opClass)
98        : AlphaStaticInst(mnem, _machInst, __opClass),
99        palFunc(PALFUNC)
100    {
101        // From the 21164 HRM (paraphrased):
102        // Bit 7 of the function code (mask 0x80) indicates
103        // whether the call is privileged (bit 7 == 0) or
104        // unprivileged (bit 7 == 1).  The privileged call table
105        // starts at 0x2000, the unprivielged call table starts at
106        // 0x3000.  Bits 5-0 (mask 0x3f) are used to calculate the
107        // offset.
108        const int palPrivMask = 0x80;
109        const int palOffsetMask = 0x3f;
110
111        // Pal call is invalid unless all other bits are 0
112        palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0);
113        palPriv = ((machInst & palPrivMask) == 0);
114        int shortPalFunc = (machInst & palOffsetMask);
115        // Add 1 to base to set pal-mode bit
116        palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6);
117    }
118
119    std::string
120    CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const
121    {
122        return csprintf("%-10s %#x", "call_pal", palFunc);
123    }
124}};
125
126def format CallPal(code, *flags) {{
127    iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags)
128    header_output = BasicDeclare.subst(iop)
129    decoder_output = BasicConstructor.subst(iop)
130    decode_block = BasicDecode.subst(iop)
131    exec_output = BasicExecute.subst(iop)
132}};
133
134////////////////////////////////////////////////////////////////////
135//
136// hw_ld, hw_st
137//
138
139output header {{
140    /**
141     * Base class for hw_ld and hw_st.
142     */
143    class HwLoadStore : public Memory
144    {
145      protected:
146
147        /// Displacement for EA calculation (signed).
148        int16_t disp;
149
150        /// Constructor
151        HwLoadStore(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
152                    StaticInstPtr _eaCompPtr = nullStaticInstPtr,
153                    StaticInstPtr _memAccPtr = nullStaticInstPtr);
154
155        std::string
156        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
157    };
158}};
159
160
161output decoder {{
162    inline
163    HwLoadStore::HwLoadStore(const char *mnem, ExtMachInst _machInst,
164                             OpClass __opClass,
165                             StaticInstPtr _eaCompPtr,
166                             StaticInstPtr _memAccPtr)
167        : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
168        disp(HW_LDST_DISP)
169    {
170        memAccessFlags = 0;
171        if (HW_LDST_PHYS) memAccessFlags |= PHYSICAL;
172        if (HW_LDST_ALT)  memAccessFlags |= ALTMODE;
173        if (HW_LDST_VPTE) memAccessFlags |= VPTE;
174        if (HW_LDST_LOCK) memAccessFlags |= LOCKED;
175    }
176
177    std::string
178    HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const
179    {
180#ifdef SS_COMPATIBLE_DISASSEMBLY
181        return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB);
182#else
183        // HW_LDST_LOCK and HW_LDST_COND are the same bit.
184        const char *lock_str =
185            (HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : "";
186
187        return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s",
188                        mnemonic, RA, disp, RB,
189                        HW_LDST_PHYS ? ",PHYS" : "",
190                        HW_LDST_ALT ? ",ALT" : "",
191                        HW_LDST_QUAD ? ",QUAD" : "",
192                        HW_LDST_VPTE ? ",VPTE" : "",
193                        lock_str);
194#endif
195    }
196}};
197
198def format HwLoad(ea_code, memacc_code, class_ext, *flags) {{
199    (header_output, decoder_output, decode_block, exec_output) = \
200        LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
201                      mem_flags = [], inst_flags = flags,
202                      base_class = 'HwLoadStore', exec_template_base = 'Load')
203}};
204
205
206def format HwStore(ea_code, memacc_code, class_ext, *flags) {{
207    (header_output, decoder_output, decode_block, exec_output) = \
208        LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
209                      mem_flags = [], inst_flags = flags,
210                      base_class = 'HwLoadStore', exec_template_base = 'Store')
211}};
212
213
214def format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext,
215                       *flags) {{
216    (header_output, decoder_output, decode_block, exec_output) = \
217        LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
218                      postacc_code, mem_flags = [], inst_flags = flags,
219                      base_class = 'HwLoadStore')
220}};
221
222
223output header {{
224    /**
225     * Base class for hw_mfpr and hw_mtpr.
226     */
227    class HwMoveIPR : public AlphaStaticInst
228    {
229      protected:
230        /// Index of internal processor register.
231        int ipr_index;
232
233        /// Constructor
234        HwMoveIPR(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
235            : AlphaStaticInst(mnem, _machInst, __opClass),
236              ipr_index(HW_IPR_IDX)
237        {
238        }
239
240        std::string
241        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
242    };
243}};
244
245output decoder {{
246    std::string
247    HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const
248    {
249        if (_numSrcRegs > 0) {
250            // must be mtpr
251            return csprintf("%-10s r%d,IPR(%#x)",
252                            mnemonic, RA, ipr_index);
253        }
254        else {
255            // must be mfpr
256            return csprintf("%-10s IPR(%#x),r%d",
257                            mnemonic, ipr_index, RA);
258        }
259    }
260}};
261
262def format HwMoveIPR(code) {{
263    iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code),
264                        ['IprAccessOp'])
265    header_output = BasicDeclare.subst(iop)
266    decoder_output = BasicConstructor.subst(iop)
267    decode_block = BasicDecode.subst(iop)
268    exec_output = BasicExecute.subst(iop)
269}};
270
271
272