static_inst.cc revision 6255:7abd88201a71
1/* Copyright (c) 2007-2008 The Florida State University
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * Authors: Stephen Hines
28 */
29
30#include "arch/arm/insts/static_inst.hh"
31#include "base/condcodes.hh"
32
33namespace ArmISA
34{
35// Shift Rm by an immediate value
36int32_t
37ArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt,
38                            uint32_t type, uint32_t cfval) const
39{
40    assert(shamt < 32);
41    ArmShiftType shiftType;
42    shiftType = (ArmShiftType)type;
43
44    switch (shiftType)
45    {
46      case LSL:
47        return base << shamt;
48      case LSR:
49        if (shamt == 0)
50            return 0;
51        else
52            return base >> shamt;
53      case ASR:
54        if (shamt == 0)
55            return (int32_t)base >> 31;
56        else
57            return (int32_t)base >> shamt;
58      case ROR:
59        if (shamt == 0)
60            return (cfval << 31) | (base >> 1); // RRX
61        else
62            return (base << (32 - shamt)) | (base >> shamt);
63      default:
64        fprintf(stderr, "Unhandled shift type\n");
65        exit(1);
66        break;
67    }
68    return 0;
69}
70
71// Shift Rm by Rs
72int32_t
73ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt,
74                           uint32_t type, uint32_t cfval) const
75{
76    enum ArmShiftType shiftType;
77    shiftType = (enum ArmShiftType) type;
78
79    switch (shiftType)
80    {
81      case LSL:
82        if (shamt >= 32)
83            return 0;
84        else
85            return base << shamt;
86      case LSR:
87        if (shamt >= 32)
88            return 0;
89        else
90            return base >> shamt;
91      case ASR:
92        if (shamt >= 32)
93            return (int32_t)base >> 31;
94        else
95            return (int32_t)base >> shamt;
96      case ROR:
97        shamt = shamt & 0x1f;
98        if (shamt == 0)
99            return base;
100        else
101            return (base << (32 - shamt)) | (base >> shamt);
102      default:
103        fprintf(stderr, "Unhandled shift type\n");
104        exit(1);
105        break;
106    }
107    return 0;
108}
109
110
111// Generate C for a shift by immediate
112bool
113ArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt,
114                               uint32_t type, uint32_t cfval) const
115{
116    enum ArmShiftType shiftType;
117    shiftType = (enum ArmShiftType) type;
118
119    switch (shiftType)
120    {
121      case LSL:
122        if (shamt == 0)
123            return cfval;
124        else
125            return (base >> (32 - shamt)) & 1;
126      case LSR:
127        if (shamt == 0)
128            return (base >> 31);
129        else
130            return (base >> (shamt - 1)) & 1;
131      case ASR:
132        if (shamt == 0)
133            return (base >> 31);
134        else
135            return (base >> (shamt - 1)) & 1;
136      case ROR:
137        shamt = shamt & 0x1f;
138        if (shamt == 0)
139            return (base & 1); // RRX
140        else
141            return (base >> (shamt - 1)) & 1;
142      default:
143        fprintf(stderr, "Unhandled shift type\n");
144        exit(1);
145        break;
146    }
147    return 0;
148}
149
150
151// Generate C for a shift by Rs
152bool
153ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt,
154                              uint32_t type, uint32_t cfval) const
155{
156    enum ArmShiftType shiftType;
157    shiftType = (enum ArmShiftType) type;
158
159    if (shamt == 0)
160        return cfval;
161
162    switch (shiftType)
163    {
164      case LSL:
165        if (shamt > 32)
166            return 0;
167        else
168            return (base >> (32 - shamt)) & 1;
169      case LSR:
170        if (shamt > 32)
171            return 0;
172        else
173            return (base >> (shamt - 1)) & 1;
174      case ASR:
175        if (shamt > 32)
176            shamt = 32;
177        return (base >> (shamt - 1)) & 1;
178      case ROR:
179        shamt = shamt & 0x1f;
180        if (shamt == 0)
181            shamt = 32;
182        return (base >> (shamt - 1)) & 1;
183      default:
184        fprintf(stderr, "Unhandled shift type\n");
185        exit(1);
186        break;
187    }
188    return 0;
189}
190
191
192// Generate the appropriate carry bit for an addition operation
193bool
194ArmStaticInst::arm_add_carry(int32_t result, int32_t lhs, int32_t rhs) const
195{
196    return findCarry(32, result, lhs, rhs);
197}
198
199// Generate the appropriate carry bit for a subtraction operation
200bool
201ArmStaticInst::arm_sub_carry(int32_t result, int32_t lhs, int32_t rhs) const
202{
203    return findCarry(32, result, lhs, ~rhs);
204}
205
206bool
207ArmStaticInst::arm_add_overflow(int32_t result, int32_t lhs, int32_t rhs) const
208{
209    return findOverflow(32, result, lhs, rhs);
210}
211
212bool
213ArmStaticInst::arm_sub_overflow(int32_t result, int32_t lhs, int32_t rhs) const
214{
215    return findOverflow(32, result, lhs, ~rhs);
216}
217
218void
219ArmStaticInst::printReg(std::ostream &os, int reg) const
220{
221    if (reg < FP_Base_DepTag) {
222        ccprintf(os, "r%d", reg);
223    }
224    else {
225        ccprintf(os, "f%d", reg - FP_Base_DepTag);
226    }
227}
228
229std::string
230ArmStaticInst::generateDisassembly(Addr pc,
231                                   const SymbolTable *symtab) const
232{
233    std::stringstream ss;
234
235    ccprintf(ss, "%-10s ", mnemonic);
236
237    return ss.str();
238}
239}
240