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