1/* 2 * Copyright (c) 2009 The University of Edinburgh 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Timothy M. Jones 29 */ 30 31#include "arch/power/insts/integer.hh" 32 33using namespace std; 34using namespace PowerISA; 35 36string 37IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 38{ 39 stringstream ss; 40 bool printDest = true; 41 bool printSrcs = true; 42 bool printSecondSrc = true; 43 44 // Generate the correct mnemonic 45 string myMnemonic(mnemonic); 46 47 // Special cases 48 if (!myMnemonic.compare("or") && _srcRegIdx[0] == _srcRegIdx[1]) { 49 myMnemonic = "mr"; 50 printSecondSrc = false; 51 } else if (!myMnemonic.compare("mtlr") || !myMnemonic.compare("cmpi")) { 52 printDest = false; 53 } else if (!myMnemonic.compare("mflr")) { 54 printSrcs = false; 55 } 56 57 // Additional characters depending on isa bits being set 58 if (oeSet) myMnemonic = myMnemonic + "o"; 59 if (rcSet) myMnemonic = myMnemonic + "."; 60 ccprintf(ss, "%-10s ", myMnemonic); 61 62 // Print the first destination only 63 if (_numDestRegs > 0 && printDest) { 64 printReg(ss, _destRegIdx[0]); 65 } 66 67 // Print the (possibly) two source registers 68 if (_numSrcRegs > 0 && printSrcs) { 69 if (_numDestRegs > 0 && printDest) { 70 ss << ", "; 71 } 72 printReg(ss, _srcRegIdx[0]); 73 if (_numSrcRegs > 1 && printSecondSrc) { 74 ss << ", "; 75 printReg(ss, _srcRegIdx[1]); 76 } 77 } 78 79 return ss.str(); 80} 81 82 83string 84IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 85{ 86 stringstream ss; 87 88 // Generate the correct mnemonic 89 string myMnemonic(mnemonic); 90 91 // Special cases 92 if (!myMnemonic.compare("addi") && _numSrcRegs == 0) { 93 myMnemonic = "li"; 94 } else if (!myMnemonic.compare("addis") && _numSrcRegs == 0) { 95 myMnemonic = "lis"; 96 } 97 ccprintf(ss, "%-10s ", myMnemonic); 98 99 // Print the first destination only 100 if (_numDestRegs > 0) { 101 printReg(ss, _destRegIdx[0]); 102 } 103 104 // Print the source register 105 if (_numSrcRegs > 0) { 106 if (_numDestRegs > 0) { 107 ss << ", "; 108 } 109 printReg(ss, _srcRegIdx[0]); 110 } 111 112 // Print the immediate value last 113 ss << ", " << (int32_t)imm; 114 115 return ss.str(); 116} 117 118 119string 120IntShiftOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 121{ 122 stringstream ss; 123 124 ccprintf(ss, "%-10s ", mnemonic); 125 126 // Print the first destination only 127 if (_numDestRegs > 0) { 128 printReg(ss, _destRegIdx[0]); 129 } 130 131 // Print the first source register 132 if (_numSrcRegs > 0) { 133 if (_numDestRegs > 0) { 134 ss << ", "; 135 } 136 printReg(ss, _srcRegIdx[0]); 137 } 138 139 // Print the shift 140 ss << ", " << sh; 141 142 return ss.str(); 143} 144 145 146string 147IntRotateOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 148{ 149 stringstream ss; 150 151 ccprintf(ss, "%-10s ", mnemonic); 152 153 // Print the first destination only 154 if (_numDestRegs > 0) { 155 printReg(ss, _destRegIdx[0]); 156 } 157 158 // Print the first source register 159 if (_numSrcRegs > 0) { 160 if (_numDestRegs > 0) { 161 ss << ", "; 162 } 163 printReg(ss, _srcRegIdx[0]); 164 } 165 166 // Print the shift, mask begin and mask end 167 ss << ", " << sh << ", " << mb << ", " << me; 168 169 return ss.str(); 170} 171