1// -*- mode:c++ -*-
2
3// Copyright (c) 2003-2005 The Regents of The University of Michigan
4// Copyright (c) 2009 The University of Edinburgh
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met: redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer;
11// redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution;
14// neither the name of the copyright holders nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Authors: Steve Reinhardt
31//          Korey Sewell
32//          Timothy M. Jones
33
34// Some instructions ignore the contents of Ra if Ra == 0,
35// so check for this.
36def template CheckRaDecode {{
37 {
38     if (RA == 0) {
39         return new %(class_name)sRaZero(machInst);
40     } else {
41         return new %(class_name)s(machInst);
42     }
43 }
44}};
45
46
47// Some instructions have extra behaviour if Rc is set.
48def template CheckRcDecode {{
49 {
50     if (RC31 == 0) {
51         return new %(class_name)s(machInst);
52     } else {
53         return new %(class_name)sRcSet(machInst);
54     }
55 }
56}};
57
58
59// Some instructions have extra behaviour if Rc and OE are set.
60def template CheckRcOeDecode {{
61 {
62     if (RC31 == 0) {
63         if (OE == 0) {
64             return new %(class_name)s(machInst);
65         } else {
66             return new %(class_name)sOeSet(machInst);
67         }
68     } else {
69         if (OE == 0) {
70             return new %(class_name)sRcSet(machInst);
71         } else {
72             return new %(class_name)sRcSetOeSet(machInst);
73         }
74     }
75 }
76}};
77
78// Branch instructions always have two versions, one which sets the link
79// register (LR).
80def template CheckLkDecode {{
81 {
82     if (LK == 0) {
83         return new %(class_name)s(machInst);
84     } else {
85         return new %(class_name)sUpdateLr(machInst);
86     }
87 }
88}};
89
90
91let {{
92
93def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
94                  base_class = 'MemOp',
95                  decode_template = BasicDecode, exec_template_base = ''):
96    # Make sure flags are in lists (convert to lists if not).
97    mem_flags = makeList(mem_flags)
98    inst_flags = makeList(inst_flags)
99
100    # Generate InstObjParams for the memory access.
101    iop = InstObjParams(name, Name, base_class,
102                        {'ea_code': ea_code,
103                         'memacc_code': memacc_code},
104                        inst_flags)
105
106    if mem_flags:
107        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
108        iop.constructor += s
109
110    fullExecTemplate = eval(exec_template_base + 'Execute')
111    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
112    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
113
114    # (header_output, decoder_output, decode_block, exec_output)
115    return (LoadStoreDeclare.subst(iop),
116            LoadStoreConstructor.subst(iop),
117            decode_template.subst(iop),
118            fullExecTemplate.subst(iop)
119            + initiateAccTemplate.subst(iop)
120            + completeAccTemplate.subst(iop))
121
122
123# The generic ALU instruction generator. Integer and fp formats calls this
124# to generate the different output sections.
125def GenAluOp(name, Name, base_class, code, inst_flags, decode_template,
126             constructor_template):
127    iop = InstObjParams(name, Name, base_class,
128                        {"code": code},
129                        inst_flags)
130    header_output = BasicDeclare.subst(iop)
131    exec_output = BasicExecute.subst(iop)
132
133    # We use constructors dependent on the Rc and OE bits being set
134    decoder_output = constructor_template.subst(iop)
135
136    # The decode block defines which version to use
137    decode_block = decode_template.subst(iop)
138    return (header_output, decoder_output, decode_block, exec_output)
139
140}};
141
142
143output header {{
144    std::string
145    inst2string(MachInst machInst);
146}};
147
148output decoder {{
149
150    std::string
151    inst2string(MachInst machInst)
152    {
153        std::string str = "";
154        uint32_t mask = 0x80000000;
155
156        for(int i=0; i < 32; i++) {
157            if ((machInst & mask) == 0) {
158                str += "0";
159            } else {
160                str += "1";
161            }
162
163            mask = mask >> 1;
164        }
165
166        return str;
167    }
168
169}};
170
171
172