sagar created this revision.
sagar added reviewers: jaydeep, clayborg.
sagar added subscribers: bhushan, mohit.bhakkad, nitesh.jain, lldb-commits.
sagar set the repository for this revision to rL LLVM.
This patch adds MSA branch instruction emulation for MIPS64.
Repository:
rL LLVM
http://reviews.llvm.org/D12356
Files:
source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
Index: source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
===================================================================
--- source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
+++ source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
@@ -302,6 +302,36 @@
Emulate_BC1ANY4T (llvm::MCInst& insn);
bool
+ Emulate_BNZB (llvm::MCInst& insn);
+
+ bool
+ Emulate_BNZH (llvm::MCInst& insn);
+
+ bool
+ Emulate_BNZW (llvm::MCInst& insn);
+
+ bool
+ Emulate_BNZD (llvm::MCInst& insn);
+
+ bool
+ Emulate_BZB (llvm::MCInst& insn);
+
+ bool
+ Emulate_BZH (llvm::MCInst& insn);
+
+ bool
+ Emulate_BZW (llvm::MCInst& insn);
+
+ bool
+ Emulate_BZD (llvm::MCInst& insn);
+
+ bool
+ Emulate_BNZV (llvm::MCInst& insn);
+
+ bool
+ Emulate_BZV (llvm::MCInst& insn);
+
+ bool
nonvolatile_reg_p (uint64_t regnum);
const char *
Index: source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
===================================================================
--- source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -256,6 +256,38 @@
case gcc_dwarf_f29_mips64: return "f29";
case gcc_dwarf_f30_mips64: return "f30";
case gcc_dwarf_f31_mips64: return "f31";
+ case gcc_dwarf_w0_mips64: return "w0";
+ case gcc_dwarf_w1_mips64: return "w1";
+ case gcc_dwarf_w2_mips64: return "w2";
+ case gcc_dwarf_w3_mips64: return "w3";
+ case gcc_dwarf_w4_mips64: return "w4";
+ case gcc_dwarf_w5_mips64: return "w5";
+ case gcc_dwarf_w6_mips64: return "w6";
+ case gcc_dwarf_w7_mips64: return "w7";
+ case gcc_dwarf_w8_mips64: return "w8";
+ case gcc_dwarf_w9_mips64: return "w9";
+ case gcc_dwarf_w10_mips64: return "w10";
+ case gcc_dwarf_w11_mips64: return "w11";
+ case gcc_dwarf_w12_mips64: return "w12";
+ case gcc_dwarf_w13_mips64: return "w13";
+ case gcc_dwarf_w14_mips64: return "w14";
+ case gcc_dwarf_w15_mips64: return "w15";
+ case gcc_dwarf_w16_mips64: return "w16";
+ case gcc_dwarf_w17_mips64: return "w17";
+ case gcc_dwarf_w18_mips64: return "w18";
+ case gcc_dwarf_w19_mips64: return "w19";
+ case gcc_dwarf_w20_mips64: return "w20";
+ case gcc_dwarf_w21_mips64: return "w21";
+ case gcc_dwarf_w22_mips64: return "w22";
+ case gcc_dwarf_w23_mips64: return "w23";
+ case gcc_dwarf_w24_mips64: return "w24";
+ case gcc_dwarf_w25_mips64: return "w25";
+ case gcc_dwarf_w26_mips64: return "w26";
+ case gcc_dwarf_w27_mips64: return "w27";
+ case gcc_dwarf_w28_mips64: return "w28";
+ case gcc_dwarf_w29_mips64: return "w29";
+ case gcc_dwarf_w30_mips64: return "w30";
+ case gcc_dwarf_w31_mips64: return "w31";
default:
break;
}
@@ -336,6 +368,41 @@
case gcc_dwarf_f31_mips64: return "f31";
case gcc_dwarf_fcsr_mips64: return "fcsr";
case gcc_dwarf_fir_mips64: return "fir";
+ case gcc_dwarf_w0_mips64: return "w0";
+ case gcc_dwarf_w1_mips64: return "w1";
+ case gcc_dwarf_w2_mips64: return "w2";
+ case gcc_dwarf_w3_mips64: return "w3";
+ case gcc_dwarf_w4_mips64: return "w4";
+ case gcc_dwarf_w5_mips64: return "w5";
+ case gcc_dwarf_w6_mips64: return "w6";
+ case gcc_dwarf_w7_mips64: return "w7";
+ case gcc_dwarf_w8_mips64: return "w8";
+ case gcc_dwarf_w9_mips64: return "w9";
+ case gcc_dwarf_w10_mips64: return "w10";
+ case gcc_dwarf_w11_mips64: return "w11";
+ case gcc_dwarf_w12_mips64: return "w12";
+ case gcc_dwarf_w13_mips64: return "w13";
+ case gcc_dwarf_w14_mips64: return "w14";
+ case gcc_dwarf_w15_mips64: return "w15";
+ case gcc_dwarf_w16_mips64: return "w16";
+ case gcc_dwarf_w17_mips64: return "w17";
+ case gcc_dwarf_w18_mips64: return "w18";
+ case gcc_dwarf_w19_mips64: return "w19";
+ case gcc_dwarf_w20_mips64: return "w20";
+ case gcc_dwarf_w21_mips64: return "w21";
+ case gcc_dwarf_w22_mips64: return "w22";
+ case gcc_dwarf_w23_mips64: return "w23";
+ case gcc_dwarf_w24_mips64: return "w24";
+ case gcc_dwarf_w25_mips64: return "w25";
+ case gcc_dwarf_w26_mips64: return "w26";
+ case gcc_dwarf_w27_mips64: return "w27";
+ case gcc_dwarf_w28_mips64: return "w28";
+ case gcc_dwarf_w29_mips64: return "w29";
+ case gcc_dwarf_w30_mips64: return "w30";
+ case gcc_dwarf_w31_mips64: return "w31";
+ case gcc_dwarf_mcsr_mips64: return "mcsr";
+ case gcc_dwarf_mir_mips64: return "mir";
+ case gcc_dwarf_config5_mips64: return "config5";
}
return nullptr;
}
@@ -374,6 +441,12 @@
reg_info.format = eFormatHex;
reg_info.encoding = eEncodingUint;
}
+ else if ((int)reg_num >= gcc_dwarf_w0_mips64 && (int)reg_num <= gcc_dwarf_w31_mips64)
+ {
+ reg_info.byte_size = 16;
+ reg_info.format = eFormatVectorOfUInt8;
+ reg_info.encoding = eEncodingVector;
+ }
else
{
return false;
@@ -474,6 +547,16 @@
{ "BC1ANY2T", &EmulateInstructionMIPS64::Emulate_BC1ANY2T, "BC1ANY2T cc, offset" },
{ "BC1ANY4F", &EmulateInstructionMIPS64::Emulate_BC1ANY4F, "BC1ANY4F cc, offset" },
{ "BC1ANY4T", &EmulateInstructionMIPS64::Emulate_BC1ANY4T, "BC1ANY4T cc, offset" },
+ { "BNZ_B", &EmulateInstructionMIPS64::Emulate_BNZB, "BNZ.b wt,s16" },
+ { "BNZ_H", &EmulateInstructionMIPS64::Emulate_BNZH, "BNZ.h wt,s16" },
+ { "BNZ_W", &EmulateInstructionMIPS64::Emulate_BNZW, "BNZ.w wt,s16" },
+ { "BNZ_D", &EmulateInstructionMIPS64::Emulate_BNZD, "BNZ.d wt,s16" },
+ { "BZ_B", &EmulateInstructionMIPS64::Emulate_BZB, "BZ.b wt,s16" },
+ { "BZ_H", &EmulateInstructionMIPS64::Emulate_BZH, "BZ.h wt,s16" },
+ { "BZ_W", &EmulateInstructionMIPS64::Emulate_BZW, "BZ.w wt,s16" },
+ { "BZ_D", &EmulateInstructionMIPS64::Emulate_BZD, "BZ.d wt,s16" },
+ { "BNZ_V", &EmulateInstructionMIPS64::Emulate_BNZV, "BNZ.V wt,s16" },
+ { "BZ_V", &EmulateInstructionMIPS64::Emulate_BZV, "BZ.V wt,s16" },
};
static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
@@ -2996,3 +3079,437 @@
return true;
}
+
+bool
+EmulateInstructionMIPS64::Emulate_BNZB (llvm::MCInst& insn)
+{
+ bool success = false, branch_hit = true;
+ uint32_t wt;
+ int64_t offset, pc, target;
+ RegisterValue reg_value;
+ uint8_t * ptr = NULL;
+
+ wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ if (ReadRegister (eRegisterKindDWARF, gcc_dwarf_w0_mips64 + wt, reg_value))
+ ptr = (uint8_t *)reg_value.GetBytes();
+ else
+ return false;
+
+ for(int i = 1 ; i < 16; i++)
+ {
+ if(*ptr == 0)
+ {
+ branch_hit = false;
+ break;
+ }
+ ptr = ptr + 1;
+ }
+
+ if(branch_hit)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextInvalid;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BNZH (llvm::MCInst& insn)
+{
+ bool success = false, branch_hit = true;
+ uint32_t wt;
+ int64_t offset, pc, target;
+ RegisterValue reg_value;
+ uint16_t * ptr = NULL;
+
+ wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ if (ReadRegister (eRegisterKindDWARF, gcc_dwarf_w0_mips64 + wt, reg_value))
+ ptr = (uint16_t *)reg_value.GetBytes();
+ else
+ return false;
+
+ for(int i = 1 ; i < 8; i++)
+ {
+ if(*ptr == 0)
+ {
+ branch_hit = false;
+ break;
+ }
+ ptr = ptr + 1;
+ }
+
+ if(branch_hit)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextInvalid;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BNZW (llvm::MCInst& insn)
+{
+ bool success = false, branch_hit = true;
+ uint32_t wt;
+ int64_t offset, pc, target;
+ RegisterValue reg_value;
+ uint32_t * ptr = NULL;
+
+ wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ if (ReadRegister (eRegisterKindDWARF, gcc_dwarf_w0_mips64 + wt, reg_value))
+ ptr = (uint32_t *)reg_value.GetBytes();
+ else
+ return false;
+
+ for(int i = 1 ; i < 4; i++)
+ {
+ if(*ptr == 0)
+ {
+ branch_hit = false;
+ break;
+ }
+ ptr = ptr + 1;
+ }
+
+ if(branch_hit)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextInvalid;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BNZD (llvm::MCInst& insn)
+{
+ bool success = false, branch_hit = true;
+ uint32_t wt;
+ int64_t offset, pc, target;
+ RegisterValue reg_value;
+ uint64_t * ptr = NULL;
+
+ wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ if (ReadRegister (eRegisterKindDWARF, gcc_dwarf_w0_mips64 + wt, reg_value))
+ ptr = (uint64_t *)reg_value.GetBytes();
+ else
+ return false;
+
+ for(int i = 1; i < 2; i++)
+ {
+ if(*ptr == 0)
+ {
+ branch_hit = false;
+ break;
+ }
+ ptr = ptr + 1;
+ }
+
+ if(branch_hit)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextInvalid;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BZB (llvm::MCInst& insn)
+{
+ bool success = false, branch_hit = true;
+ uint32_t wt;
+ int64_t offset, pc, target;
+ RegisterValue reg_value;
+ uint8_t * ptr = NULL;
+
+ wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ if (ReadRegister (eRegisterKindDWARF, gcc_dwarf_w0_mips64 + wt, reg_value))
+ ptr = (uint8_t *)reg_value.GetBytes();
+ else
+ return false;
+
+ for(int i = 1 ; i < 16 ; i++)
+ {
+ if(*ptr != 0)
+ {
+ branch_hit = false;
+ break;
+ }
+ ptr = ptr + 1;
+ }
+
+ if(branch_hit)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextInvalid;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BZH (llvm::MCInst& insn)
+{
+ bool success = false, branch_hit = true;
+ uint32_t wt;
+ int64_t offset, pc, target;
+ RegisterValue reg_value;
+ uint16_t * ptr = NULL;
+
+ wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ if (ReadRegister (eRegisterKindDWARF, gcc_dwarf_w0_mips64 + wt, reg_value))
+ ptr = (uint16_t *)reg_value.GetBytes();
+ else
+ return false;
+
+ for(int i = 1 ; i < 8; i++)
+ {
+ if(*ptr != 0)
+ {
+ branch_hit = false;
+ break;
+ }
+ ptr = ptr + 1;
+ }
+
+ if(branch_hit)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextInvalid;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BZW (llvm::MCInst& insn)
+{
+ bool success = false, branch_hit = true;
+ uint32_t wt;
+ int64_t offset, pc, target;
+ RegisterValue reg_value;
+ uint32_t * ptr = NULL;
+
+ wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ if (ReadRegister (eRegisterKindDWARF, gcc_dwarf_w0_mips64 + wt, reg_value))
+ ptr = (uint32_t *)reg_value.GetBytes();
+ else
+ return false;
+
+ for(int i = 1 ; i < 4; i++)
+ {
+ if(*ptr != 0)
+ {
+ branch_hit = false;
+ break;
+ }
+ ptr = ptr + 1;
+ }
+
+ if(branch_hit)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextInvalid;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BZD (llvm::MCInst& insn)
+{
+ bool success = false, branch_hit = true;
+ uint32_t wt;
+ int64_t offset, pc, target;
+ RegisterValue reg_value;
+ uint64_t * ptr = NULL;
+
+ wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ if (ReadRegister (eRegisterKindDWARF, gcc_dwarf_w0_mips64 + wt, reg_value))
+ ptr = (uint64_t *)reg_value.GetBytes();
+ else
+ return false;
+
+ for(int i = 1 ; i < 2; i++)
+ {
+ if(*ptr != 0)
+ {
+ branch_hit = false;
+ break;
+ }
+ ptr = ptr + 1;
+ }
+
+ if(branch_hit)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextInvalid;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BNZV (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t wt;
+ int64_t offset, pc, target;
+ llvm::APInt wr_val;
+ llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
+ llvm::APInt zero_value = llvm::APInt::getNullValue(128);
+ RegisterValue reg_value;
+
+ wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ if (ReadRegister (eRegisterKindDWARF, gcc_dwarf_w0_mips64 + wt, reg_value))
+ wr_val = reg_value.GetAsUInt128(fail_value);
+ else
+ return false;
+
+ if(!llvm::APInt::isSameValue(zero_value, wr_val))
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextInvalid;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BZV (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t wt;
+ int64_t offset, pc, target;
+ llvm::APInt wr_val;
+ llvm::APInt fail_value = llvm::APInt::getMaxValue(128);
+ llvm::APInt zero_value = llvm::APInt::getNullValue(128);
+ RegisterValue reg_value;
+
+ wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ if (ReadRegister (eRegisterKindDWARF, gcc_dwarf_w0_mips64 + wt, reg_value))
+ wr_val = reg_value.GetAsUInt128(fail_value);
+ else
+ return false;
+
+ if(llvm::APInt::isSameValue(zero_value, wr_val))
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextInvalid;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits