1 //===-- ABISysV_hexagon.cpp -------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "ABISysV_hexagon.h"
14 // Other libraries and framework includes
15 #include "llvm/ADT/Triple.h"
16 #include "llvm/IR/DerivedTypes.h"
19 #include "lldb/Core/Module.h"
20 #include "lldb/Core/PluginManager.h"
21 #include "lldb/Core/RegisterValue.h"
22 #include "lldb/Core/Value.h"
23 #include "lldb/Core/ValueObjectConstResult.h"
24 #include "lldb/Core/ValueObjectMemory.h"
25 #include "lldb/Core/ValueObjectRegister.h"
26 #include "lldb/Symbol/UnwindPlan.h"
27 #include "lldb/Target/Process.h"
28 #include "lldb/Target/RegisterContext.h"
29 #include "lldb/Target/StackFrame.h"
30 #include "lldb/Target/Target.h"
31 #include "lldb/Target/Thread.h"
32 #include "lldb/Utility/ConstString.h"
33 #include "lldb/Utility/DataExtractor.h"
34 #include "lldb/Utility/Log.h"
35 #include "lldb/Utility/Status.h"
38 using namespace lldb_private;
40 static RegisterInfo g_register_infos[] = {
48 {0, 0, LLDB_INVALID_REGNUM, 0, 0},
59 {1, 1, LLDB_INVALID_REGNUM, 1, 1},
70 {2, 2, LLDB_INVALID_REGNUM, 2, 2},
81 {3, 3, LLDB_INVALID_REGNUM, 3, 3},
92 {4, 4, LLDB_INVALID_REGNUM, 4, 4},
103 {5, 5, LLDB_INVALID_REGNUM, 5, 5},
114 {6, 6, LLDB_INVALID_REGNUM, 6, 6},
125 {7, 7, LLDB_INVALID_REGNUM, 7, 7},
136 {8, 8, LLDB_INVALID_REGNUM, 8, 8},
147 {9, 9, LLDB_INVALID_REGNUM, 9, 9},
158 {10, 10, LLDB_INVALID_REGNUM, 10, 10},
169 {11, 11, LLDB_INVALID_REGNUM, 11, 11},
180 {12, 12, LLDB_INVALID_REGNUM, 12, 12},
191 {13, 13, LLDB_INVALID_REGNUM, 13, 13},
202 {14, 14, LLDB_INVALID_REGNUM, 14, 14},
213 {15, 15, LLDB_INVALID_REGNUM, 15, 15},
224 {16, 16, LLDB_INVALID_REGNUM, 16, 16},
235 {17, 17, LLDB_INVALID_REGNUM, 17, 17},
246 {18, 18, LLDB_INVALID_REGNUM, 18, 18},
257 {19, 19, LLDB_INVALID_REGNUM, 19, 19},
268 {20, 20, LLDB_INVALID_REGNUM, 20, 20},
279 {21, 21, LLDB_INVALID_REGNUM, 21, 21},
290 {22, 22, LLDB_INVALID_REGNUM, 22, 22},
301 {23, 23, LLDB_INVALID_REGNUM, 23, 23},
312 {24, 24, LLDB_INVALID_REGNUM, 24, 24},
323 {25, 25, LLDB_INVALID_REGNUM, 25, 25},
334 {26, 26, LLDB_INVALID_REGNUM, 26, 26},
345 {27, 27, LLDB_INVALID_REGNUM, 27, 27},
356 {28, 28, LLDB_INVALID_REGNUM, 28, 28},
367 {29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29},
378 {30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30},
389 {31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31},
400 {32, 32, LLDB_INVALID_REGNUM, 32, 32},
411 {33, 33, LLDB_INVALID_REGNUM, 33, 33},
422 {34, 34, LLDB_INVALID_REGNUM, 34, 34},
433 {35, 35, LLDB_INVALID_REGNUM, 35, 35},
438 // --> hexagon-v4/5/55/56-sim.xml
445 {36, 36, LLDB_INVALID_REGNUM, 36, 36},
457 {37, 37, LLDB_INVALID_REGNUM, 37, 37},
469 {38, 38, LLDB_INVALID_REGNUM, 38, 38},
480 {39, 39, LLDB_INVALID_REGNUM, 39, 39},
491 {40, 40, LLDB_INVALID_REGNUM, 40, 40},
502 {41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41},
513 {42, 42, LLDB_INVALID_REGNUM, 42, 42},
524 {43, 43, LLDB_INVALID_REGNUM, 43, 43},
535 {44, 44, LLDB_INVALID_REGNUM, 44, 44},
546 {45, 45, LLDB_INVALID_REGNUM, 45, 45},
558 {46, 46, LLDB_INVALID_REGNUM, 46, 46},
569 {47, 47, LLDB_INVALID_REGNUM, 47, 47},
580 {48, 48, LLDB_INVALID_REGNUM, 48, 48},
591 {49, 49, LLDB_INVALID_REGNUM, 49, 49},
602 {50, 50, LLDB_INVALID_REGNUM, 50, 50},
613 {51, 51, LLDB_INVALID_REGNUM, 51, 51},
624 {52, 52, LLDB_INVALID_REGNUM, 52, 52},
635 {53, 53, LLDB_INVALID_REGNUM, 53, 53},
646 {54, 54, LLDB_INVALID_REGNUM, 54, 54},
657 {55, 55, LLDB_INVALID_REGNUM, 55, 55},
668 {56, 56, LLDB_INVALID_REGNUM, 56, 56},
679 {57, 57, LLDB_INVALID_REGNUM, 57, 57},
690 {58, 58, LLDB_INVALID_REGNUM, 58, 58},
701 {59, 59, LLDB_INVALID_REGNUM, 59, 59},
712 {60, 60, LLDB_INVALID_REGNUM, 60, 60},
723 {61, 61, LLDB_INVALID_REGNUM, 61, 61},
734 {62, 62, LLDB_INVALID_REGNUM, 62, 62},
745 {63, 63, LLDB_INVALID_REGNUM, 63, 63},
757 {64, 64, LLDB_INVALID_REGNUM, 64, 64},
769 {65, 65, LLDB_INVALID_REGNUM, 65, 65},
781 {66, 66, LLDB_INVALID_REGNUM, 66, 66},
792 {67, 67, LLDB_INVALID_REGNUM, 67, 67},
803 {68, 68, LLDB_INVALID_REGNUM, 68, 68},
814 {69, 69, LLDB_INVALID_REGNUM, 69, 69},
825 {70, 70, LLDB_INVALID_REGNUM, 70, 70},
836 {71, 71, LLDB_INVALID_REGNUM, 71, 71},
847 {72, 72, LLDB_INVALID_REGNUM, 72, 72},
859 {73, 73, LLDB_INVALID_REGNUM, 73, 73},
871 {74, 74, LLDB_INVALID_REGNUM, 74, 74},
883 {75, 75, LLDB_INVALID_REGNUM, 75, 75},
894 {76, 76, LLDB_INVALID_REGNUM, 76, 76},
905 {77, 77, LLDB_INVALID_REGNUM, 77, 77},
916 {78, 78, LLDB_INVALID_REGNUM, 78, 78},
927 {79, 79, LLDB_INVALID_REGNUM, 79, 79},
939 {80, 80, LLDB_INVALID_REGNUM, 80, 80},
950 {81, 81, LLDB_INVALID_REGNUM, 81, 81},
961 {82, 82, LLDB_INVALID_REGNUM, 82, 82},
972 {83, 83, LLDB_INVALID_REGNUM, 83, 83},
978 static const uint32_t k_num_register_infos =
979 sizeof(g_register_infos) / sizeof(RegisterInfo);
980 static bool g_register_info_names_constified = false;
982 const lldb_private::RegisterInfo *
983 ABISysV_hexagon::GetRegisterInfoArray(uint32_t &count) {
984 // Make the C-string names and alt_names for the register infos into const
985 // C-string values by having the ConstString unique the names in the global
986 // constant C-string pool.
987 if (!g_register_info_names_constified) {
988 g_register_info_names_constified = true;
989 for (uint32_t i = 0; i < k_num_register_infos; ++i) {
990 if (g_register_infos[i].name)
991 g_register_infos[i].name =
992 ConstString(g_register_infos[i].name).GetCString();
993 if (g_register_infos[i].alt_name)
994 g_register_infos[i].alt_name =
995 ConstString(g_register_infos[i].alt_name).GetCString();
998 count = k_num_register_infos;
999 return g_register_infos;
1003 http://en.wikipedia.org/wiki/Red_zone_%28computing%29
1005 In computing, a red zone is a fixed size area in memory beyond the stack
1006 pointer that has not been
1007 "allocated". This region of memory is not to be modified by
1008 interrupt/exception/signal handlers.
1009 This allows the space to be used for temporary data without the extra
1010 overhead of modifying the
1011 stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC
1013 128 byte red zone though it is not documented.
1015 size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
1017 //------------------------------------------------------------------
1019 //------------------------------------------------------------------
1022 ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1023 static ABISP g_abi_sp;
1024 if (arch.GetTriple().getArch() == llvm::Triple::hexagon) {
1026 g_abi_sp.reset(new ABISysV_hexagon(process_sp));
1032 bool ABISysV_hexagon::PrepareTrivialCall(Thread &thread, lldb::addr_t sp,
1033 lldb::addr_t pc, lldb::addr_t ra,
1034 llvm::ArrayRef<addr_t> args) const {
1035 // we don't use the traditional trivial call specialized for jit
1042 // . safeguard the current stack
1043 // . how can we know that the called function will create its own frame
1045 // . we could manually make a new stack first:
1049 // 5. SP = SP ( since no locals in our temp frame )
1052 // . variable argument list parameters are not passed via registers, they are
1054 // the stack. This presents us with a problem, since we need to know when
1056 // starts. Currently I can find out if a function is varg, but not how many
1057 // real parameters it takes. Thus I don't know when to start spilling the
1059 // the time being, to progress, I will assume that it takes on real parameter
1061 // the vargs list starts.
1064 // . how do we adhere to the stack alignment requirements
1067 // . handle 64bit values and their register / stack requirements
1070 #define HEX_ABI_DEBUG 0
1071 bool ABISysV_hexagon::PrepareTrivialCall(
1072 Thread &thread, lldb::addr_t sp, lldb::addr_t pc, lldb::addr_t ra,
1073 llvm::Type &prototype, llvm::ArrayRef<ABI::CallArgument> args) const {
1074 // default number of register passed arguments for varg functions
1075 const int nVArgRegParams = 1;
1078 // grab the process so we have access to the memory for spilling
1079 lldb::ProcessSP proc = thread.GetProcess();
1081 // get the register context for modifying all of the registers
1082 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1086 uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1087 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1088 if (pc_reg == LLDB_INVALID_REGNUM)
1091 uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1092 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
1093 if (ra_reg == LLDB_INVALID_REGNUM)
1096 uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1097 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1098 if (sp_reg == LLDB_INVALID_REGNUM)
1101 // push host data onto target
1102 for (size_t i = 0; i < args.size(); i++) {
1103 const ABI::CallArgument &arg = args[i];
1104 // skip over target values
1105 if (arg.type == ABI::CallArgument::TargetValue)
1107 // round up to 8 byte multiple
1108 size_t argSize = (arg.size | 0x7) + 1;
1110 // create space on the stack for this data
1113 // write this argument onto the stack of the host process
1114 proc->WriteMemory(sp, arg.data_ap.get(), arg.size, error);
1118 // update the argument with the target pointer
1119 // XXX: This is a gross hack for getting around the const
1120 *const_cast<lldb::addr_t *>(&arg.value) = sp;
1124 // print the original stack pointer
1125 printf("sp : %04" PRIx64 " \n", sp);
1128 // make sure number of parameters matches prototype
1129 assert(prototype.getFunctionNumParams() == args.size());
1131 // check if this is a variable argument function
1132 bool isVArg = prototype.isFunctionVarArg();
1134 // number of arguments passed by register
1135 int nRegArgs = nVArgRegParams;
1137 // number of arguments is limited by [R0 : R5] space
1138 nRegArgs = args.size();
1143 // pass arguments that are passed via registers
1144 for (int i = 0; i < nRegArgs; i++) {
1145 // get the parameter as a u32
1146 uint32_t param = (uint32_t)args[i].value;
1147 // write argument into register
1148 if (!reg_ctx->WriteRegisterFromUnsigned(i, param))
1152 // number of arguments to spill onto stack
1153 int nSpillArgs = args.size() - nRegArgs;
1154 // make space on the stack for arguments
1155 sp -= 4 * nSpillArgs;
1156 // align stack on an 8 byte boundary
1160 // arguments that are passed on the stack
1161 for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) {
1162 // get the parameter as a u32
1163 uint32_t param = (uint32_t)args[i].value;
1164 // write argument to stack
1165 proc->WriteMemory(sp + offs, (void *)¶m, sizeof(param), error);
1166 if (!error.Success())
1172 // update registers with current function call state
1173 reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);
1174 reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);
1175 reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);
1178 // quick and dirty stack dumper for debugging
1179 for (int i = -8; i < 8; i++) {
1181 lldb::addr_t addr = sp + i * 4;
1182 proc->ReadMemory(addr, (void *)&data, sizeof(data), error);
1183 printf("\n0x%04" PRIx64 " 0x%08x ", addr, data);
1193 bool ABISysV_hexagon::GetArgumentValues(Thread &thread,
1194 ValueList &values) const {
1199 ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1200 lldb::ValueObjectSP &new_value_sp) {
1205 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectSimple(
1206 Thread &thread, CompilerType &return_compiler_type) const {
1207 ValueObjectSP return_valobj_sp;
1208 return return_valobj_sp;
1211 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectImpl(
1212 Thread &thread, CompilerType &return_compiler_type) const {
1213 ValueObjectSP return_valobj_sp;
1214 return return_valobj_sp;
1217 // called when we are on the first instruction of a new function for hexagon
1218 // the return address is in RA (R31)
1219 bool ABISysV_hexagon::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1220 unwind_plan.Clear();
1221 unwind_plan.SetRegisterKind(eRegisterKindGeneric);
1222 unwind_plan.SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA);
1224 UnwindPlan::RowSP row(new UnwindPlan::Row);
1226 // Our Call Frame Address is the stack pointer value
1227 row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 4);
1230 // The previous PC is in the LR
1231 row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC,
1232 LLDB_REGNUM_GENERIC_RA, true);
1233 unwind_plan.AppendRow(row);
1235 unwind_plan.SetSourceName("hexagon at-func-entry default");
1236 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1240 bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1241 unwind_plan.Clear();
1242 unwind_plan.SetRegisterKind(eRegisterKindGeneric);
1244 uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;
1245 uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
1246 uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
1248 UnwindPlan::RowSP row(new UnwindPlan::Row);
1250 row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8);
1252 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true);
1253 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, true);
1254 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1256 unwind_plan.AppendRow(row);
1257 unwind_plan.SetSourceName("hexagon default unwind plan");
1258 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1259 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1264 Register Usage Saved By
1266 R0 - R5 parameters(a) -
1267 R6 - R15 Scratch(b) Caller
1268 R16 - R27 Scratch Callee
1269 R28 Scratch(b) Caller
1270 R29 - R31 Stack Frames Callee(c)
1271 P3:0 Processor State Caller
1273 a = the caller can change parameter values
1274 b = R14 - R15 and R28 are used by the procedure linkage table
1275 c = R29 - R31 are saved and restored by allocframe() and deallocframe()
1277 bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) {
1278 return !RegisterIsCalleeSaved(reg_info);
1281 bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1282 int reg = ((reg_info->byte_offset) / 4);
1284 bool save = (reg >= 16) && (reg <= 27);
1285 save |= (reg >= 29) && (reg <= 32);
1290 void ABISysV_hexagon::Initialize() {
1291 PluginManager::RegisterPlugin(GetPluginNameStatic(),
1292 "System V ABI for hexagon targets",
1296 void ABISysV_hexagon::Terminate() {
1297 PluginManager::UnregisterPlugin(CreateInstance);
1300 lldb_private::ConstString ABISysV_hexagon::GetPluginNameStatic() {
1301 static ConstString g_name("sysv-hexagon");
1305 //------------------------------------------------------------------
1306 // PluginInterface protocol
1307 //------------------------------------------------------------------
1309 lldb_private::ConstString ABISysV_hexagon::GetPluginName() {
1310 return GetPluginNameStatic();
1313 uint32_t ABISysV_hexagon::GetPluginVersion() { return 1; }
1315 // get value object specialized to work with llvm IR types
1317 ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread &thread,
1318 llvm::Type &retType) const {
1320 ValueObjectSP vObjSP;
1322 // get the current register context
1323 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1327 // for now just pop R0 to find the return value
1328 const lldb_private::RegisterInfo *r0_info =
1329 reg_ctx->GetRegisterInfoAtIndex(0);
1330 if (r0_info == nullptr)
1334 if (retType.isVoidTy()) {
1335 value.GetScalar() = 0;
1337 // integer / pointer return type
1338 else if (retType.isIntegerTy() || retType.isPointerTy()) {
1339 // read r0 register value
1340 lldb_private::RegisterValue r0_value;
1341 if (!reg_ctx->ReadRegister(r0_info, r0_value))
1344 // push r0 into value
1345 uint32_t r0_u32 = r0_value.GetAsUInt32();
1347 // account for integer size
1348 if (retType.isIntegerTy() && retType.isSized()) {
1349 uint64_t size = retType.getScalarSizeInBits();
1350 uint64_t mask = (1ull << size) - 1;
1351 // mask out higher order bits then the type we expect
1355 value.GetScalar() = r0_u32;
1357 // unsupported return type
1361 // pack the value into a ValueObjectSP
1362 vObjSP = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
1363 value, ConstString(""));