branch.hh revision 7149:97666c2fc7a5
1/*
2 * Copyright (c) 2010 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2007-2008 The Florida State University
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Stephen Hines
41 */
42#ifndef __ARCH_ARM_INSTS_BRANCH_HH__
43#define __ARCH_ARM_INSTS_BRANCH_HH__
44
45#include "arch/arm/insts/pred_inst.hh"
46
47namespace ArmISA
48{
49/**
50 * Base class for instructions whose disassembly is not purely a
51 * function of the machine instruction (i.e., it depends on the
52 * PC).  This class overrides the disassemble() method to check
53 * the PC and symbol table values before re-using a cached
54 * disassembly string.  This is necessary for branches and jumps,
55 * where the disassembly string includes the target address (which
56 * may depend on the PC and/or symbol table).
57 */
58class PCDependentDisassembly : public PredOp
59{
60  protected:
61    /// Cached program counter from last disassembly
62    mutable Addr cachedPC;
63
64    /// Cached symbol table pointer from last disassembly
65    mutable const SymbolTable *cachedSymtab;
66
67    /// Constructor
68    PCDependentDisassembly(const char *mnem, ExtMachInst _machInst,
69                           OpClass __opClass)
70        : PredOp(mnem, _machInst, __opClass),
71          cachedPC(0), cachedSymtab(0)
72    {
73    }
74
75    const std::string &
76    disassemble(Addr pc, const SymbolTable *symtab) const;
77};
78
79// Branch to a target computed with an immediate
80class BranchImm : public PredOp
81{
82  protected:
83    int32_t imm;
84
85  public:
86    BranchImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
87              int32_t _imm) :
88        PredOp(mnem, _machInst, __opClass), imm(_imm)
89    {}
90};
91
92// Conditionally Branch to a target computed with an immediate
93class BranchImmCond : public BranchImm
94{
95  protected:
96    // This will mask the condition code stored for PredOp. Ideally these two
97    // class would cooperate, but they're not set up to do that at the moment.
98    ConditionCode condCode;
99
100  public:
101    BranchImmCond(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
102                  int32_t _imm, ConditionCode _condCode) :
103        BranchImm(mnem, _machInst, __opClass, _imm), condCode(_condCode)
104    {}
105};
106
107// Branch to a target computed with a register
108class BranchReg : public PredOp
109{
110  protected:
111    IntRegIndex op1;
112
113  public:
114    BranchReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
115              IntRegIndex _op1) :
116        PredOp(mnem, _machInst, __opClass), op1(_op1)
117    {}
118};
119
120// Conditionally Branch to a target computed with a register
121class BranchRegCond : public BranchReg
122{
123  protected:
124    // This will mask the condition code stored for PredOp. Ideally these two
125    // class would cooperate, but they're not set up to do that at the moment.
126    ConditionCode condCode;
127
128  public:
129    BranchRegCond(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
130                  IntRegIndex _op1, ConditionCode _condCode) :
131        BranchReg(mnem, _machInst, __opClass, _op1), condCode(_condCode)
132    {}
133};
134
135// Branch to a target computed with two registers
136class BranchRegReg : public PredOp
137{
138  protected:
139    IntRegIndex op1;
140    IntRegIndex op2;
141
142  public:
143    BranchRegReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
144                 IntRegIndex _op1, IntRegIndex _op2) :
145        PredOp(mnem, _machInst, __opClass), op1(_op1), op2(_op2)
146    {}
147};
148
149// Branch to a target computed with an immediate and a register
150class BranchImmReg : public PredOp
151{
152  protected:
153    int32_t imm;
154    IntRegIndex op1;
155
156  public:
157    BranchImmReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
158                 int32_t _imm, IntRegIndex _op1) :
159        PredOp(mnem, _machInst, __opClass), imm(_imm), op1(_op1)
160    {}
161};
162
163/**
164 * Base class for branches (PC-relative control transfers),
165 * conditional or unconditional.
166 */
167class Branch : public PCDependentDisassembly
168{
169  protected:
170    /// target address (signed) Displacement .
171    int32_t disp;
172
173    /// Constructor.
174    Branch(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
175        : PCDependentDisassembly(mnem, _machInst, __opClass),
176          disp(machInst.offset << 2)
177    {
178        //If Bit 26 is 1 then Sign Extend
179        if ( (disp & 0x02000000) > 0  ) {
180            disp |=  0xFC000000;
181        }
182    }
183
184    Addr branchTarget(Addr branchPC) const;
185
186    std::string
187    generateDisassembly(Addr pc, const SymbolTable *symtab) const;
188};
189
190/**
191 * Base class for branch and exchange instructions on the ARM
192 */
193class BranchExchange : public PredOp
194{
195  protected:
196    /// Constructor
197    BranchExchange(const char *mnem, ExtMachInst _machInst,
198                           OpClass __opClass)
199        : PredOp(mnem, _machInst, __opClass)
200    {
201    }
202
203    std::string
204    generateDisassembly(Addr pc, const SymbolTable *symtab) const;
205};
206
207}
208
209#endif //__ARCH_ARM_INSTS_BRANCH_HH__
210