SparcInstPrinter.c revision a726402513883fb8cec45958c457c788e128f353
105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh//===-- SparcInstPrinter.cpp - Convert Sparc MCInst to assembly syntax --------===// 205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh// 305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh// The LLVM Compiler Infrastructure 405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh// 505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh// This file is distributed under the University of Illinois Open Source 605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh// License. See LICENSE.TXT for details. 705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh// 805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh//===----------------------------------------------------------------------===// 905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh// 1005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh// This class prints an Sparc MCInst to a .s file. 1105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh// 1205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh//===----------------------------------------------------------------------===// 1305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 1405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh/* Capstone Disassembly Engine */ 1505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */ 1605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 178598a219f303802198439f9fc0884dffe19b3b11Nguyen Anh Quynh#ifdef CAPSTONE_HAS_SPARC 188598a219f303802198439f9fc0884dffe19b3b11Nguyen Anh Quynh 1905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#include <stdio.h> 2005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#include <stdlib.h> 2105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#include <string.h> 2205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 2305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#include "SparcInstPrinter.h" 2405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#include "../../MCInst.h" 2505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#include "../../utils.h" 2605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#include "../../SStream.h" 2705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#include "../../MCRegisterInfo.h" 2805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#include "../../MathExtras.h" 2905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#include "SparcMapping.h" 3005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 3105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#include "Sparc.h" 3205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 339b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynhstatic char *getRegisterName(unsigned RegNo); 3405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynhstatic void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI); 3505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynhstatic void printMemOperand(MCInst *MI, int opNum, SStream *O, const char *Modifier); 3605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynhstatic void printOperand(MCInst *MI, int opNum, SStream *O); 3705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 3805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynhstatic void set_mem_access(MCInst *MI, bool status) 3905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh{ 4005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (MI->csh->detail != CS_OPT_ON) 4105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh return; 4205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 4305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh MI->csh->doing_mem = status; 4405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 4505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (status) { 4629fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_MEM; 4729fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base = SPARC_REG_INVALID; 4829fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.disp = 0; 4905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } else { 5005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh // done, create the next operand slot 5129fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh MI->flat_insn->detail->sparc.op_count++; 5205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 5305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh} 5405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 5564564815081383385309135f6ae5b8502d28a9aaNguyen Anh Quynhvoid Sparc_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci) 5605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh{ 5705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (((cs_struct *)ud)->detail != CS_OPT_ON) 5805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh return; 5905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 6005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh // fix up some instructions 6105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (insn->id == SPARC_INS_CASX) { 6205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh // first op is actually a memop, not regop 6305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh insn->detail->sparc.operands[0].type = SPARC_OP_MEM; 6405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh insn->detail->sparc.operands[0].mem.base = insn->detail->sparc.operands[0].reg; 6505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh insn->detail->sparc.operands[0].mem.disp = 0; 6605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 6705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh} 6805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 6905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynhstatic void printRegName(SStream *OS, unsigned RegNo) 7005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh{ 719b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh SStream_concat0(OS, "%"); 729b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh SStream_concat0(OS, getRegisterName(RegNo)); 7305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh} 7405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 7505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#define GET_INSTRINFO_ENUM 7605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#include "SparcGenInstrInfo.inc" 7705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 7805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#define GET_REGINFO_ENUM 7905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#include "SparcGenRegisterInfo.inc" 8005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 8105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynhstatic bool printSparcAliasInstr(MCInst *MI, SStream *O) 8205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh{ 8305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh switch (MCInst_getOpcode(MI)) { 8405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh default: return false; 8505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_JMPLrr: 8605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_JMPLri: 8705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (MCInst_getNumOperands(MI) != 3) 8805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh return false; 8905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (!MCOperand_isReg(MCInst_getOperand(MI, 0))) 9005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh return false; 9105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 9205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh switch (MCOperand_getReg(MCInst_getOperand(MI, 0))) { 9305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh default: return false; 9405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_G0: // jmp $addr | ret | retl 9505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (MCOperand_isImm(MCInst_getOperand(MI, 2)) && 9605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh MCOperand_getImm(MCInst_getOperand(MI, 2)) == 8) { 9705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh switch(MCOperand_getReg(MCInst_getOperand(MI, 1))) { 9805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh default: break; 999b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh case SP_I7: SStream_concat0(O, "ret"); return true; 1009b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh case SP_O7: SStream_concat0(O, "retl"); return true; 10105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 10205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 10305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 1049b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh SStream_concat0(O, "jmp\t"); 10505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh printMemOperand(MI, 1, O, NULL); 10605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh return true; 10705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_O7: // call $addr 1089b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh SStream_concat0(O, "call "); 10905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh printMemOperand(MI, 1, O, NULL); 11005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh return true; 11105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 11205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_V9FCMPS: 11305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_V9FCMPD: 11405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_V9FCMPQ: 11505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_V9FCMPES: 11605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_V9FCMPED: 11705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_V9FCMPEQ: 11805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (MI->csh->mode & CS_MODE_V9 || (MCInst_getNumOperands(MI) != 3) || 11905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh (!MCOperand_isReg(MCInst_getOperand(MI, 0))) || 12005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh (MCOperand_getReg(MCInst_getOperand(MI, 0)) != SP_FCC0)) 12105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh return false; 12205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh // if V8, skip printing %fcc0. 12305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh switch(MCInst_getOpcode(MI)) { 12405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh default: 1259b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh case SP_V9FCMPS: SStream_concat0(O, "fcmps\t"); break; 1269b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh case SP_V9FCMPD: SStream_concat0(O, "fcmpd\t"); break; 1279b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh case SP_V9FCMPQ: SStream_concat0(O, "fcmpq\t"); break; 1289b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh case SP_V9FCMPES: SStream_concat0(O, "fcmpes\t"); break; 1299b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh case SP_V9FCMPED: SStream_concat0(O, "fcmped\t"); break; 1309b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh case SP_V9FCMPEQ: SStream_concat0(O, "fcmpeq\t"); break; 13105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 13205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh printOperand(MI, 1, O); 1339b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh SStream_concat0(O, ", "); 13405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh printOperand(MI, 2, O); 13505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh return true; 13605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 13705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh} 13805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 13905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynhstatic void printOperand(MCInst *MI, int opNum, SStream *O) 14005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh{ 14105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh int Imm; 14205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh unsigned reg; 14305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh MCOperand *MO = MCInst_getOperand(MI, opNum); 14405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 14505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (MCOperand_isReg(MO)) { 14605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh reg = MCOperand_getReg(MO); 14705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh printRegName(O, reg); 14805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh reg = Sparc_map_register(reg); 14905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 15005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (MI->csh->detail) { 15105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (MI->csh->doing_mem) { 15229fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh if (MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base) 15329fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.index = reg; 15405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh else 15529fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base = reg; 15605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } else { 15729fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_REG; 15829fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].reg = reg; 15929fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh MI->flat_insn->detail->sparc.op_count++; 16005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 16105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 16205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 16305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh return; 16405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 16505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 16605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (MCOperand_isImm(MO)) { 16705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh Imm = (int)MCOperand_getImm(MO); 168a3c9bd678faed15a0f8c3463933c79b541246317Nguyen Anh Quynh if (Imm >= 0) { 169a3c9bd678faed15a0f8c3463933c79b541246317Nguyen Anh Quynh if (Imm > HEX_THRESHOLD) 170a3c9bd678faed15a0f8c3463933c79b541246317Nguyen Anh Quynh SStream_concat(O, "0x%x", Imm); 171a3c9bd678faed15a0f8c3463933c79b541246317Nguyen Anh Quynh else 172a3c9bd678faed15a0f8c3463933c79b541246317Nguyen Anh Quynh SStream_concat(O, "%u", Imm); 173a3c9bd678faed15a0f8c3463933c79b541246317Nguyen Anh Quynh } else { 174a3c9bd678faed15a0f8c3463933c79b541246317Nguyen Anh Quynh if (Imm < -HEX_THRESHOLD) 175a3c9bd678faed15a0f8c3463933c79b541246317Nguyen Anh Quynh SStream_concat(O, "-0x%x", -Imm); 176a3c9bd678faed15a0f8c3463933c79b541246317Nguyen Anh Quynh else 177a3c9bd678faed15a0f8c3463933c79b541246317Nguyen Anh Quynh SStream_concat(O, "-%u", -Imm); 178a3c9bd678faed15a0f8c3463933c79b541246317Nguyen Anh Quynh } 17905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 18005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (MI->csh->detail) { 18105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (MI->csh->doing_mem) { 18229fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.disp = Imm; 18305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } else { 18429fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_IMM; 18529fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].imm = Imm; 18629fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh MI->flat_insn->detail->sparc.op_count++; 18705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 18805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 18905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 19005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 19105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh return; 19205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh} 19305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 19405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynhstatic void printMemOperand(MCInst *MI, int opNum, SStream *O, const char *Modifier) 19505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh{ 19605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh MCOperand *MO; 19705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 19805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh set_mem_access(MI, true); 19905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh printOperand(MI, opNum, O); 20005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 20105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh // If this is an ADD operand, emit it like normal operands. 20205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (Modifier && !strcmp(Modifier, "arith")) { 2039b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh SStream_concat0(O, ", "); 20405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh printOperand(MI, opNum + 1, O); 20505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh set_mem_access(MI, false); 20605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh return; 20705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 20805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 20905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh MO = MCInst_getOperand(MI, opNum + 1); 21005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 21105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (MCOperand_isReg(MO) && (MCOperand_getReg(MO) == SP_G0)) { 21205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh set_mem_access(MI, false); 21305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh return; // don't print "+%g0" 21405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 21505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 21605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (MCOperand_isImm(MO) && (MCOperand_getImm(MO) == 0)) { 21705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh set_mem_access(MI, false); 21805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh return; // don't print "+0" 21905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 22005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 2219b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh SStream_concat0(O, "+"); 22205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 22305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh printOperand(MI, opNum + 1, O); 22405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh set_mem_access(MI, false); 22505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh} 22605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 22705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynhstatic void printCCOperand(MCInst *MI, int opNum, SStream *O) 22805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh{ 2295d6383e335bdc98b0f14c43e7221ad61b85f8d08Nguyen Anh Quynh int CC = (int)MCOperand_getImm(MCInst_getOperand(MI, opNum)) + 256; 23005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 23105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh switch (MCInst_getOpcode(MI)) { 23205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh default: break; 23305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_FBCOND: 23405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_FBCONDA: 23505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_BPFCC: 23605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_BPFCCA: 23705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_BPFCCNT: 23805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_BPFCCANT: 23905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_MOVFCCrr: case SP_V9MOVFCCrr: 24005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_MOVFCCri: case SP_V9MOVFCCri: 24105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_FMOVS_FCC: case SP_V9FMOVS_FCC: 24205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_FMOVD_FCC: case SP_V9FMOVD_FCC: 24305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh case SP_FMOVQ_FCC: case SP_V9FMOVQ_FCC: 24405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh // Make sure CC is a fp conditional flag. 2455d6383e335bdc98b0f14c43e7221ad61b85f8d08Nguyen Anh Quynh CC = (CC < 16+256) ? (CC + 16) : CC; 24605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh break; 24705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 24805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 2499b91de0ae349c5e9be25c40dd5901483d76a0939Nguyen Anh Quynh SStream_concat0(O, SPARCCondCodeToString((sparc_cc)CC)); 25005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 25105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (MI->csh->detail) 25229fd0f640567d3db5e1deacd2f78da75aedb2628Nguyen Anh Quynh MI->flat_insn->detail->sparc.cc = (sparc_cc)CC; 25305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh} 25405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 25505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 25605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynhstatic bool printGetPCX(MCInst *MI, unsigned opNum, SStream *O) 25705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh{ 25805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh return true; 25905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh} 26005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 26105e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 26205e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#define PRINT_ALIAS_INSTR 26305e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh#include "SparcGenAsmWriter.inc" 26405e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 26505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynhvoid Sparc_printInst(MCInst *MI, SStream *O, void *Info) 26605e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh{ 267a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh char *mnem, *p; 268a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh char instr[64]; // Sparc has no instruction this long 26905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh 27005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh mnem = printAliasInstr(MI, O, Info); 271159ddbd99fae8c435f815aa5251bb6466160cb91Nguyen Anh Quynh if (mnem) { 272159ddbd99fae8c435f815aa5251bb6466160cb91Nguyen Anh Quynh // fixup instruction id due to the change in alias instruction 273a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh strncpy(instr, mnem, strlen(mnem)); 274a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh instr[strlen(mnem)] = '\0'; 275a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh // does this contains hint with a coma? 276a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh p = strchr(instr, ','); 277a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh if (p) 278a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh *p = '\0'; // now instr only has instruction mnemonic 279a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh MCInst_setOpcodePub(MI, Sparc_map_insn(instr)); 280a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh switch(MCInst_getOpcode(MI)) { 281a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_BCOND: 282a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_BCONDA: 283a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_BPICCANT: 284a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_BPICCNT: 285a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_BPXCCANT: 286a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_BPXCCNT: 287a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_TXCCri: 288a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_TXCCrr: 289a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh if (MI->csh->detail) { 290a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh // skip 'b', 't' 291a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 1); 292a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); 293a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh } 294a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh break; 295a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_BPFCCANT: 296a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_BPFCCNT: 297a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh if (MI->csh->detail) { 298a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh // skip 'fb' 299a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 2); 300a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); 301a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh } 302a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh break; 303a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_FMOVD_ICC: 304a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_FMOVD_XCC: 305a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_FMOVQ_ICC: 306a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_FMOVQ_XCC: 307a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_FMOVS_ICC: 308a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_FMOVS_XCC: 309a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh if (MI->csh->detail) { 310a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh // skip 'fmovd', 'fmovq', 'fmovs' 311a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 5); 312a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); 313a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh } 314a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh break; 315a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_MOVICCri: 316a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_MOVICCrr: 317a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_MOVXCCri: 318a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_MOVXCCrr: 319a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh if (MI->csh->detail) { 320a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh // skip 'mov' 321a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 3); 322a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); 323a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh } 324a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh break; 325a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_V9FMOVD_FCC: 326a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_V9FMOVQ_FCC: 327a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_V9FMOVS_FCC: 328a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh if (MI->csh->detail) { 329a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh // skip 'fmovd', 'fmovq', 'fmovs' 330a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 5); 331a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); 332a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh } 333a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh break; 334a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_V9MOVFCCri: 335a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh case SP_V9MOVFCCrr: 336a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh if (MI->csh->detail) { 337a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh // skip 'mov' 338a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 3); 339a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); 340a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh } 341a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh break; 342a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh default: 343a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh break; 344a726402513883fb8cec45958c457c788e128f353Nguyen Anh Quynh } 34505e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh cs_mem_free(mnem); 346159ddbd99fae8c435f815aa5251bb6466160cb91Nguyen Anh Quynh } else { 34705e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh if (!printSparcAliasInstr(MI, O)) 34805e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh printInstruction(MI, O, NULL); 34905e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh } 35005e27138aef5dea54576d2916d92d2f7bd1f3956Nguyen Anh Quynh} 3518598a219f303802198439f9fc0884dffe19b3b11Nguyen Anh Quynh 3528598a219f303802198439f9fc0884dffe19b3b11Nguyen Anh Quynh#endif 353