xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
15ffd83dbSDimitry Andric //===-- ABISysV_mips.cpp --------------------------------------------------===//
25ffd83dbSDimitry Andric //
35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ffd83dbSDimitry Andric //
75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
85ffd83dbSDimitry Andric 
95ffd83dbSDimitry Andric #include "ABISysV_mips.h"
105ffd83dbSDimitry Andric 
115ffd83dbSDimitry Andric #include "llvm/ADT/STLExtras.h"
12*06c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
135ffd83dbSDimitry Andric 
145ffd83dbSDimitry Andric #include "lldb/Core/Module.h"
155ffd83dbSDimitry Andric #include "lldb/Core/PluginManager.h"
165ffd83dbSDimitry Andric #include "lldb/Core/Value.h"
175ffd83dbSDimitry Andric #include "lldb/Core/ValueObjectConstResult.h"
185ffd83dbSDimitry Andric #include "lldb/Core/ValueObjectMemory.h"
195ffd83dbSDimitry Andric #include "lldb/Core/ValueObjectRegister.h"
205ffd83dbSDimitry Andric #include "lldb/Symbol/UnwindPlan.h"
215ffd83dbSDimitry Andric #include "lldb/Target/Process.h"
225ffd83dbSDimitry Andric #include "lldb/Target/RegisterContext.h"
235ffd83dbSDimitry Andric #include "lldb/Target/StackFrame.h"
245ffd83dbSDimitry Andric #include "lldb/Target/Target.h"
255ffd83dbSDimitry Andric #include "lldb/Target/Thread.h"
265ffd83dbSDimitry Andric #include "lldb/Utility/ConstString.h"
275ffd83dbSDimitry Andric #include "lldb/Utility/DataExtractor.h"
2881ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h"
295ffd83dbSDimitry Andric #include "lldb/Utility/Log.h"
305ffd83dbSDimitry Andric #include "lldb/Utility/RegisterValue.h"
315ffd83dbSDimitry Andric #include "lldb/Utility/Status.h"
32bdd1243dSDimitry Andric #include <optional>
335ffd83dbSDimitry Andric 
345ffd83dbSDimitry Andric using namespace lldb;
355ffd83dbSDimitry Andric using namespace lldb_private;
365ffd83dbSDimitry Andric 
375ffd83dbSDimitry Andric LLDB_PLUGIN_DEFINE(ABISysV_mips)
385ffd83dbSDimitry Andric 
395ffd83dbSDimitry Andric enum dwarf_regnums {
405ffd83dbSDimitry Andric   dwarf_r0 = 0,
415ffd83dbSDimitry Andric   dwarf_r1,
425ffd83dbSDimitry Andric   dwarf_r2,
435ffd83dbSDimitry Andric   dwarf_r3,
445ffd83dbSDimitry Andric   dwarf_r4,
455ffd83dbSDimitry Andric   dwarf_r5,
465ffd83dbSDimitry Andric   dwarf_r6,
475ffd83dbSDimitry Andric   dwarf_r7,
485ffd83dbSDimitry Andric   dwarf_r8,
495ffd83dbSDimitry Andric   dwarf_r9,
505ffd83dbSDimitry Andric   dwarf_r10,
515ffd83dbSDimitry Andric   dwarf_r11,
525ffd83dbSDimitry Andric   dwarf_r12,
535ffd83dbSDimitry Andric   dwarf_r13,
545ffd83dbSDimitry Andric   dwarf_r14,
555ffd83dbSDimitry Andric   dwarf_r15,
565ffd83dbSDimitry Andric   dwarf_r16,
575ffd83dbSDimitry Andric   dwarf_r17,
585ffd83dbSDimitry Andric   dwarf_r18,
595ffd83dbSDimitry Andric   dwarf_r19,
605ffd83dbSDimitry Andric   dwarf_r20,
615ffd83dbSDimitry Andric   dwarf_r21,
625ffd83dbSDimitry Andric   dwarf_r22,
635ffd83dbSDimitry Andric   dwarf_r23,
645ffd83dbSDimitry Andric   dwarf_r24,
655ffd83dbSDimitry Andric   dwarf_r25,
665ffd83dbSDimitry Andric   dwarf_r26,
675ffd83dbSDimitry Andric   dwarf_r27,
685ffd83dbSDimitry Andric   dwarf_r28,
695ffd83dbSDimitry Andric   dwarf_r29,
705ffd83dbSDimitry Andric   dwarf_r30,
715ffd83dbSDimitry Andric   dwarf_r31,
725ffd83dbSDimitry Andric   dwarf_sr,
735ffd83dbSDimitry Andric   dwarf_lo,
745ffd83dbSDimitry Andric   dwarf_hi,
755ffd83dbSDimitry Andric   dwarf_bad,
765ffd83dbSDimitry Andric   dwarf_cause,
775ffd83dbSDimitry Andric   dwarf_pc
785ffd83dbSDimitry Andric };
795ffd83dbSDimitry Andric 
805ffd83dbSDimitry Andric static const RegisterInfo g_register_infos[] = {
815ffd83dbSDimitry Andric     //  NAME      ALT    SZ OFF ENCODING        FORMAT         EH_FRAME
825ffd83dbSDimitry Andric     //  DWARF                   GENERIC                     PROCESS PLUGINS
835ffd83dbSDimitry Andric     //  LLDB NATIVE            VALUE REGS  INVALIDATE REGS
845ffd83dbSDimitry Andric     //  ========  ======  == === =============  ===========    ============
855ffd83dbSDimitry Andric     //  ==============          ============                =================
865ffd83dbSDimitry Andric     //  ===================     ========== =================
875ffd83dbSDimitry Andric     {"r0",
885ffd83dbSDimitry Andric      "zero",
895ffd83dbSDimitry Andric      4,
905ffd83dbSDimitry Andric      0,
915ffd83dbSDimitry Andric      eEncodingUint,
925ffd83dbSDimitry Andric      eFormatHex,
935ffd83dbSDimitry Andric      {dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
945ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
955ffd83dbSDimitry Andric      nullptr,
965ffd83dbSDimitry Andric      nullptr,
97*06c3fb27SDimitry Andric      nullptr,
98349cc55cSDimitry Andric     },
995ffd83dbSDimitry Andric     {"r1",
1005ffd83dbSDimitry Andric      "AT",
1015ffd83dbSDimitry Andric      4,
1025ffd83dbSDimitry Andric      0,
1035ffd83dbSDimitry Andric      eEncodingUint,
1045ffd83dbSDimitry Andric      eFormatHex,
1055ffd83dbSDimitry Andric      {dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1065ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
1075ffd83dbSDimitry Andric      nullptr,
1085ffd83dbSDimitry Andric      nullptr,
109*06c3fb27SDimitry Andric      nullptr,
110349cc55cSDimitry Andric     },
1115ffd83dbSDimitry Andric     {"r2",
1125ffd83dbSDimitry Andric      "v0",
1135ffd83dbSDimitry Andric      4,
1145ffd83dbSDimitry Andric      0,
1155ffd83dbSDimitry Andric      eEncodingUint,
1165ffd83dbSDimitry Andric      eFormatHex,
1175ffd83dbSDimitry Andric      {dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1185ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
1195ffd83dbSDimitry Andric      nullptr,
1205ffd83dbSDimitry Andric      nullptr,
121*06c3fb27SDimitry Andric      nullptr,
122349cc55cSDimitry Andric     },
1235ffd83dbSDimitry Andric     {"r3",
1245ffd83dbSDimitry Andric      "v1",
1255ffd83dbSDimitry Andric      4,
1265ffd83dbSDimitry Andric      0,
1275ffd83dbSDimitry Andric      eEncodingUint,
1285ffd83dbSDimitry Andric      eFormatHex,
1295ffd83dbSDimitry Andric      {dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1305ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
1315ffd83dbSDimitry Andric      nullptr,
1325ffd83dbSDimitry Andric      nullptr,
133*06c3fb27SDimitry Andric      nullptr,
134349cc55cSDimitry Andric     },
1355ffd83dbSDimitry Andric     {"r4",
136349cc55cSDimitry Andric      nullptr,
1375ffd83dbSDimitry Andric      4,
1385ffd83dbSDimitry Andric      0,
1395ffd83dbSDimitry Andric      eEncodingUint,
1405ffd83dbSDimitry Andric      eFormatHex,
1415ffd83dbSDimitry Andric      {dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
1425ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
1435ffd83dbSDimitry Andric      nullptr,
1445ffd83dbSDimitry Andric      nullptr,
145*06c3fb27SDimitry Andric      nullptr,
146349cc55cSDimitry Andric     },
1475ffd83dbSDimitry Andric     {"r5",
148349cc55cSDimitry Andric      nullptr,
1495ffd83dbSDimitry Andric      4,
1505ffd83dbSDimitry Andric      0,
1515ffd83dbSDimitry Andric      eEncodingUint,
1525ffd83dbSDimitry Andric      eFormatHex,
1535ffd83dbSDimitry Andric      {dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
1545ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
1555ffd83dbSDimitry Andric      nullptr,
1565ffd83dbSDimitry Andric      nullptr,
157*06c3fb27SDimitry Andric      nullptr,
158349cc55cSDimitry Andric     },
1595ffd83dbSDimitry Andric     {"r6",
160349cc55cSDimitry Andric      nullptr,
1615ffd83dbSDimitry Andric      4,
1625ffd83dbSDimitry Andric      0,
1635ffd83dbSDimitry Andric      eEncodingUint,
1645ffd83dbSDimitry Andric      eFormatHex,
1655ffd83dbSDimitry Andric      {dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
1665ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
1675ffd83dbSDimitry Andric      nullptr,
1685ffd83dbSDimitry Andric      nullptr,
169*06c3fb27SDimitry Andric      nullptr,
170349cc55cSDimitry Andric     },
1715ffd83dbSDimitry Andric     {"r7",
172349cc55cSDimitry Andric      nullptr,
1735ffd83dbSDimitry Andric      4,
1745ffd83dbSDimitry Andric      0,
1755ffd83dbSDimitry Andric      eEncodingUint,
1765ffd83dbSDimitry Andric      eFormatHex,
1775ffd83dbSDimitry Andric      {dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
1785ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
1795ffd83dbSDimitry Andric      nullptr,
1805ffd83dbSDimitry Andric      nullptr,
181*06c3fb27SDimitry Andric      nullptr,
182349cc55cSDimitry Andric     },
1835ffd83dbSDimitry Andric     {"r8",
1845ffd83dbSDimitry Andric      "arg5",
1855ffd83dbSDimitry Andric      4,
1865ffd83dbSDimitry Andric      0,
1875ffd83dbSDimitry Andric      eEncodingUint,
1885ffd83dbSDimitry Andric      eFormatHex,
1895ffd83dbSDimitry Andric      {dwarf_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1905ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
1915ffd83dbSDimitry Andric      nullptr,
1925ffd83dbSDimitry Andric      nullptr,
193*06c3fb27SDimitry Andric      nullptr,
194349cc55cSDimitry Andric     },
1955ffd83dbSDimitry Andric     {"r9",
1965ffd83dbSDimitry Andric      "arg6",
1975ffd83dbSDimitry Andric      4,
1985ffd83dbSDimitry Andric      0,
1995ffd83dbSDimitry Andric      eEncodingUint,
2005ffd83dbSDimitry Andric      eFormatHex,
2015ffd83dbSDimitry Andric      {dwarf_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
2025ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
2035ffd83dbSDimitry Andric      nullptr,
2045ffd83dbSDimitry Andric      nullptr,
205*06c3fb27SDimitry Andric      nullptr,
206349cc55cSDimitry Andric     },
2075ffd83dbSDimitry Andric     {"r10",
2085ffd83dbSDimitry Andric      "arg7",
2095ffd83dbSDimitry Andric      4,
2105ffd83dbSDimitry Andric      0,
2115ffd83dbSDimitry Andric      eEncodingUint,
2125ffd83dbSDimitry Andric      eFormatHex,
2135ffd83dbSDimitry Andric      {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
2145ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
2155ffd83dbSDimitry Andric      nullptr,
2165ffd83dbSDimitry Andric      nullptr,
217*06c3fb27SDimitry Andric      nullptr,
218349cc55cSDimitry Andric     },
2195ffd83dbSDimitry Andric     {"r11",
2205ffd83dbSDimitry Andric      "arg8",
2215ffd83dbSDimitry Andric      4,
2225ffd83dbSDimitry Andric      0,
2235ffd83dbSDimitry Andric      eEncodingUint,
2245ffd83dbSDimitry Andric      eFormatHex,
2255ffd83dbSDimitry Andric      {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
2265ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
2275ffd83dbSDimitry Andric      nullptr,
2285ffd83dbSDimitry Andric      nullptr,
229*06c3fb27SDimitry Andric      nullptr,
230349cc55cSDimitry Andric     },
2315ffd83dbSDimitry Andric     {"r12",
2325ffd83dbSDimitry Andric      nullptr,
2335ffd83dbSDimitry Andric      4,
2345ffd83dbSDimitry Andric      0,
2355ffd83dbSDimitry Andric      eEncodingUint,
2365ffd83dbSDimitry Andric      eFormatHex,
2375ffd83dbSDimitry Andric      {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
2385ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
2395ffd83dbSDimitry Andric      nullptr,
2405ffd83dbSDimitry Andric      nullptr,
241*06c3fb27SDimitry Andric      nullptr,
242349cc55cSDimitry Andric     },
2435ffd83dbSDimitry Andric     {"r13",
2445ffd83dbSDimitry Andric      nullptr,
2455ffd83dbSDimitry Andric      4,
2465ffd83dbSDimitry Andric      0,
2475ffd83dbSDimitry Andric      eEncodingUint,
2485ffd83dbSDimitry Andric      eFormatHex,
2495ffd83dbSDimitry Andric      {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
2505ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
2515ffd83dbSDimitry Andric      nullptr,
2525ffd83dbSDimitry Andric      nullptr,
253*06c3fb27SDimitry Andric      nullptr,
254349cc55cSDimitry Andric     },
2555ffd83dbSDimitry Andric     {"r14",
2565ffd83dbSDimitry Andric      nullptr,
2575ffd83dbSDimitry Andric      4,
2585ffd83dbSDimitry Andric      0,
2595ffd83dbSDimitry Andric      eEncodingUint,
2605ffd83dbSDimitry Andric      eFormatHex,
2615ffd83dbSDimitry Andric      {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
2625ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
2635ffd83dbSDimitry Andric      nullptr,
2645ffd83dbSDimitry Andric      nullptr,
265*06c3fb27SDimitry Andric      nullptr,
266349cc55cSDimitry Andric     },
2675ffd83dbSDimitry Andric     {"r15",
2685ffd83dbSDimitry Andric      nullptr,
2695ffd83dbSDimitry Andric      4,
2705ffd83dbSDimitry Andric      0,
2715ffd83dbSDimitry Andric      eEncodingUint,
2725ffd83dbSDimitry Andric      eFormatHex,
2735ffd83dbSDimitry Andric      {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
2745ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
2755ffd83dbSDimitry Andric      nullptr,
2765ffd83dbSDimitry Andric      nullptr,
277*06c3fb27SDimitry Andric      nullptr,
278349cc55cSDimitry Andric     },
2795ffd83dbSDimitry Andric     {"r16",
2805ffd83dbSDimitry Andric      nullptr,
2815ffd83dbSDimitry Andric      4,
2825ffd83dbSDimitry Andric      0,
2835ffd83dbSDimitry Andric      eEncodingUint,
2845ffd83dbSDimitry Andric      eFormatHex,
2855ffd83dbSDimitry Andric      {dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
2865ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
2875ffd83dbSDimitry Andric      nullptr,
2885ffd83dbSDimitry Andric      nullptr,
289*06c3fb27SDimitry Andric      nullptr,
290349cc55cSDimitry Andric     },
2915ffd83dbSDimitry Andric     {"r17",
2925ffd83dbSDimitry Andric      nullptr,
2935ffd83dbSDimitry Andric      4,
2945ffd83dbSDimitry Andric      0,
2955ffd83dbSDimitry Andric      eEncodingUint,
2965ffd83dbSDimitry Andric      eFormatHex,
2975ffd83dbSDimitry Andric      {dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
2985ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
2995ffd83dbSDimitry Andric      nullptr,
3005ffd83dbSDimitry Andric      nullptr,
301*06c3fb27SDimitry Andric      nullptr,
302349cc55cSDimitry Andric     },
3035ffd83dbSDimitry Andric     {"r18",
3045ffd83dbSDimitry Andric      nullptr,
3055ffd83dbSDimitry Andric      4,
3065ffd83dbSDimitry Andric      0,
3075ffd83dbSDimitry Andric      eEncodingUint,
3085ffd83dbSDimitry Andric      eFormatHex,
3095ffd83dbSDimitry Andric      {dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
3105ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
3115ffd83dbSDimitry Andric      nullptr,
3125ffd83dbSDimitry Andric      nullptr,
313*06c3fb27SDimitry Andric      nullptr,
314349cc55cSDimitry Andric     },
3155ffd83dbSDimitry Andric     {"r19",
3165ffd83dbSDimitry Andric      nullptr,
3175ffd83dbSDimitry Andric      4,
3185ffd83dbSDimitry Andric      0,
3195ffd83dbSDimitry Andric      eEncodingUint,
3205ffd83dbSDimitry Andric      eFormatHex,
3215ffd83dbSDimitry Andric      {dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
3225ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
3235ffd83dbSDimitry Andric      nullptr,
3245ffd83dbSDimitry Andric      nullptr,
325*06c3fb27SDimitry Andric      nullptr,
326349cc55cSDimitry Andric     },
3275ffd83dbSDimitry Andric     {"r20",
3285ffd83dbSDimitry Andric      nullptr,
3295ffd83dbSDimitry Andric      4,
3305ffd83dbSDimitry Andric      0,
3315ffd83dbSDimitry Andric      eEncodingUint,
3325ffd83dbSDimitry Andric      eFormatHex,
3335ffd83dbSDimitry Andric      {dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
3345ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
3355ffd83dbSDimitry Andric      nullptr,
3365ffd83dbSDimitry Andric      nullptr,
337*06c3fb27SDimitry Andric      nullptr,
338349cc55cSDimitry Andric     },
3395ffd83dbSDimitry Andric     {"r21",
3405ffd83dbSDimitry Andric      nullptr,
3415ffd83dbSDimitry Andric      4,
3425ffd83dbSDimitry Andric      0,
3435ffd83dbSDimitry Andric      eEncodingUint,
3445ffd83dbSDimitry Andric      eFormatHex,
3455ffd83dbSDimitry Andric      {dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
3465ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
3475ffd83dbSDimitry Andric      nullptr,
3485ffd83dbSDimitry Andric      nullptr,
349*06c3fb27SDimitry Andric      nullptr,
350349cc55cSDimitry Andric     },
3515ffd83dbSDimitry Andric     {"r22",
3525ffd83dbSDimitry Andric      nullptr,
3535ffd83dbSDimitry Andric      4,
3545ffd83dbSDimitry Andric      0,
3555ffd83dbSDimitry Andric      eEncodingUint,
3565ffd83dbSDimitry Andric      eFormatHex,
3575ffd83dbSDimitry Andric      {dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
3585ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
3595ffd83dbSDimitry Andric      nullptr,
3605ffd83dbSDimitry Andric      nullptr,
361*06c3fb27SDimitry Andric      nullptr,
362349cc55cSDimitry Andric     },
3635ffd83dbSDimitry Andric     {"r23",
3645ffd83dbSDimitry Andric      nullptr,
3655ffd83dbSDimitry Andric      4,
3665ffd83dbSDimitry Andric      0,
3675ffd83dbSDimitry Andric      eEncodingUint,
3685ffd83dbSDimitry Andric      eFormatHex,
3695ffd83dbSDimitry Andric      {dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
3705ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
3715ffd83dbSDimitry Andric      nullptr,
3725ffd83dbSDimitry Andric      nullptr,
373*06c3fb27SDimitry Andric      nullptr,
374349cc55cSDimitry Andric     },
3755ffd83dbSDimitry Andric     {"r24",
3765ffd83dbSDimitry Andric      nullptr,
3775ffd83dbSDimitry Andric      4,
3785ffd83dbSDimitry Andric      0,
3795ffd83dbSDimitry Andric      eEncodingUint,
3805ffd83dbSDimitry Andric      eFormatHex,
3815ffd83dbSDimitry Andric      {dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
3825ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
3835ffd83dbSDimitry Andric      nullptr,
3845ffd83dbSDimitry Andric      nullptr,
385*06c3fb27SDimitry Andric      nullptr,
386349cc55cSDimitry Andric     },
3875ffd83dbSDimitry Andric     {"r25",
3885ffd83dbSDimitry Andric      nullptr,
3895ffd83dbSDimitry Andric      4,
3905ffd83dbSDimitry Andric      0,
3915ffd83dbSDimitry Andric      eEncodingUint,
3925ffd83dbSDimitry Andric      eFormatHex,
3935ffd83dbSDimitry Andric      {dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
3945ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
3955ffd83dbSDimitry Andric      nullptr,
3965ffd83dbSDimitry Andric      nullptr,
397*06c3fb27SDimitry Andric      nullptr,
398349cc55cSDimitry Andric     },
3995ffd83dbSDimitry Andric     {"r26",
4005ffd83dbSDimitry Andric      nullptr,
4015ffd83dbSDimitry Andric      4,
4025ffd83dbSDimitry Andric      0,
4035ffd83dbSDimitry Andric      eEncodingUint,
4045ffd83dbSDimitry Andric      eFormatHex,
4055ffd83dbSDimitry Andric      {dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
4065ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
4075ffd83dbSDimitry Andric      nullptr,
4085ffd83dbSDimitry Andric      nullptr,
409*06c3fb27SDimitry Andric      nullptr,
410349cc55cSDimitry Andric     },
4115ffd83dbSDimitry Andric     {"r27",
4125ffd83dbSDimitry Andric      nullptr,
4135ffd83dbSDimitry Andric      4,
4145ffd83dbSDimitry Andric      0,
4155ffd83dbSDimitry Andric      eEncodingUint,
4165ffd83dbSDimitry Andric      eFormatHex,
4175ffd83dbSDimitry Andric      {dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
4185ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
4195ffd83dbSDimitry Andric      nullptr,
4205ffd83dbSDimitry Andric      nullptr,
421*06c3fb27SDimitry Andric      nullptr,
422349cc55cSDimitry Andric     },
4235ffd83dbSDimitry Andric     {"r28",
4245ffd83dbSDimitry Andric      "gp",
4255ffd83dbSDimitry Andric      4,
4265ffd83dbSDimitry Andric      0,
4275ffd83dbSDimitry Andric      eEncodingUint,
4285ffd83dbSDimitry Andric      eFormatHex,
4295ffd83dbSDimitry Andric      {dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
4305ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
4315ffd83dbSDimitry Andric      nullptr,
4325ffd83dbSDimitry Andric      nullptr,
433*06c3fb27SDimitry Andric      nullptr,
434349cc55cSDimitry Andric     },
4355ffd83dbSDimitry Andric     {"r29",
436349cc55cSDimitry Andric      nullptr,
4375ffd83dbSDimitry Andric      4,
4385ffd83dbSDimitry Andric      0,
4395ffd83dbSDimitry Andric      eEncodingUint,
4405ffd83dbSDimitry Andric      eFormatHex,
4415ffd83dbSDimitry Andric      {dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
4425ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
4435ffd83dbSDimitry Andric      nullptr,
4445ffd83dbSDimitry Andric      nullptr,
445*06c3fb27SDimitry Andric      nullptr,
446349cc55cSDimitry Andric     },
4475ffd83dbSDimitry Andric     {"r30",
448349cc55cSDimitry Andric      nullptr,
4495ffd83dbSDimitry Andric      4,
4505ffd83dbSDimitry Andric      0,
4515ffd83dbSDimitry Andric      eEncodingUint,
4525ffd83dbSDimitry Andric      eFormatHex,
4535ffd83dbSDimitry Andric      {dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
4545ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
4555ffd83dbSDimitry Andric      nullptr,
4565ffd83dbSDimitry Andric      nullptr,
457*06c3fb27SDimitry Andric      nullptr,
458349cc55cSDimitry Andric     },
4595ffd83dbSDimitry Andric     {"r31",
460349cc55cSDimitry Andric      nullptr,
4615ffd83dbSDimitry Andric      4,
4625ffd83dbSDimitry Andric      0,
4635ffd83dbSDimitry Andric      eEncodingUint,
4645ffd83dbSDimitry Andric      eFormatHex,
4655ffd83dbSDimitry Andric      {dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
4665ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
4675ffd83dbSDimitry Andric      nullptr,
4685ffd83dbSDimitry Andric      nullptr,
469*06c3fb27SDimitry Andric      nullptr,
470349cc55cSDimitry Andric     },
4715ffd83dbSDimitry Andric     {"sr",
4725ffd83dbSDimitry Andric      nullptr,
4735ffd83dbSDimitry Andric      4,
4745ffd83dbSDimitry Andric      0,
4755ffd83dbSDimitry Andric      eEncodingUint,
4765ffd83dbSDimitry Andric      eFormatHex,
4775ffd83dbSDimitry Andric      {dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
4785ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
4795ffd83dbSDimitry Andric      nullptr,
4805ffd83dbSDimitry Andric      nullptr,
481*06c3fb27SDimitry Andric      nullptr,
482349cc55cSDimitry Andric     },
4835ffd83dbSDimitry Andric     {"lo",
4845ffd83dbSDimitry Andric      nullptr,
4855ffd83dbSDimitry Andric      4,
4865ffd83dbSDimitry Andric      0,
4875ffd83dbSDimitry Andric      eEncodingUint,
4885ffd83dbSDimitry Andric      eFormatHex,
4895ffd83dbSDimitry Andric      {dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
4905ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
4915ffd83dbSDimitry Andric      nullptr,
4925ffd83dbSDimitry Andric      nullptr,
493*06c3fb27SDimitry Andric      nullptr,
494349cc55cSDimitry Andric     },
4955ffd83dbSDimitry Andric     {"hi",
4965ffd83dbSDimitry Andric      nullptr,
4975ffd83dbSDimitry Andric      4,
4985ffd83dbSDimitry Andric      0,
4995ffd83dbSDimitry Andric      eEncodingUint,
5005ffd83dbSDimitry Andric      eFormatHex,
5015ffd83dbSDimitry Andric      {dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
5025ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
5035ffd83dbSDimitry Andric      nullptr,
5045ffd83dbSDimitry Andric      nullptr,
505*06c3fb27SDimitry Andric      nullptr,
506349cc55cSDimitry Andric     },
5075ffd83dbSDimitry Andric     {"bad",
5085ffd83dbSDimitry Andric      nullptr,
5095ffd83dbSDimitry Andric      4,
5105ffd83dbSDimitry Andric      0,
5115ffd83dbSDimitry Andric      eEncodingUint,
5125ffd83dbSDimitry Andric      eFormatHex,
5135ffd83dbSDimitry Andric      {dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
5145ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
5155ffd83dbSDimitry Andric      nullptr,
5165ffd83dbSDimitry Andric      nullptr,
517*06c3fb27SDimitry Andric      nullptr,
518349cc55cSDimitry Andric     },
5195ffd83dbSDimitry Andric     {"cause",
5205ffd83dbSDimitry Andric      nullptr,
5215ffd83dbSDimitry Andric      4,
5225ffd83dbSDimitry Andric      0,
5235ffd83dbSDimitry Andric      eEncodingUint,
5245ffd83dbSDimitry Andric      eFormatHex,
5255ffd83dbSDimitry Andric      {dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
5265ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
5275ffd83dbSDimitry Andric      nullptr,
5285ffd83dbSDimitry Andric      nullptr,
529*06c3fb27SDimitry Andric      nullptr,
530349cc55cSDimitry Andric     },
5315ffd83dbSDimitry Andric     {"pc",
5325ffd83dbSDimitry Andric      nullptr,
5335ffd83dbSDimitry Andric      4,
5345ffd83dbSDimitry Andric      0,
5355ffd83dbSDimitry Andric      eEncodingUint,
5365ffd83dbSDimitry Andric      eFormatHex,
5375ffd83dbSDimitry Andric      {dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
5385ffd83dbSDimitry Andric       LLDB_INVALID_REGNUM},
5395ffd83dbSDimitry Andric      nullptr,
5405ffd83dbSDimitry Andric      nullptr,
541*06c3fb27SDimitry Andric      nullptr,
542349cc55cSDimitry Andric     },
5435ffd83dbSDimitry Andric };
5445ffd83dbSDimitry Andric 
545bdd1243dSDimitry Andric static const uint32_t k_num_register_infos = std::size(g_register_infos);
5465ffd83dbSDimitry Andric 
5475ffd83dbSDimitry Andric const lldb_private::RegisterInfo *
GetRegisterInfoArray(uint32_t & count)5485ffd83dbSDimitry Andric ABISysV_mips::GetRegisterInfoArray(uint32_t &count) {
5495ffd83dbSDimitry Andric   count = k_num_register_infos;
5505ffd83dbSDimitry Andric   return g_register_infos;
5515ffd83dbSDimitry Andric }
5525ffd83dbSDimitry Andric 
GetRedZoneSize() const5535ffd83dbSDimitry Andric size_t ABISysV_mips::GetRedZoneSize() const { return 0; }
5545ffd83dbSDimitry Andric 
5555ffd83dbSDimitry Andric // Static Functions
5565ffd83dbSDimitry Andric 
5575ffd83dbSDimitry Andric ABISP
CreateInstance(lldb::ProcessSP process_sp,const ArchSpec & arch)5585ffd83dbSDimitry Andric ABISysV_mips::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
5595ffd83dbSDimitry Andric   const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
5605ffd83dbSDimitry Andric   if ((arch_type == llvm::Triple::mips) ||
5615ffd83dbSDimitry Andric       (arch_type == llvm::Triple::mipsel)) {
5625ffd83dbSDimitry Andric     return ABISP(
5635ffd83dbSDimitry Andric         new ABISysV_mips(std::move(process_sp), MakeMCRegisterInfo(arch)));
5645ffd83dbSDimitry Andric   }
5655ffd83dbSDimitry Andric   return ABISP();
5665ffd83dbSDimitry Andric }
5675ffd83dbSDimitry Andric 
PrepareTrivialCall(Thread & thread,addr_t sp,addr_t func_addr,addr_t return_addr,llvm::ArrayRef<addr_t> args) const5685ffd83dbSDimitry Andric bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp,
5695ffd83dbSDimitry Andric                                       addr_t func_addr, addr_t return_addr,
5705ffd83dbSDimitry Andric                                       llvm::ArrayRef<addr_t> args) const {
57181ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Expressions);
5725ffd83dbSDimitry Andric 
5735ffd83dbSDimitry Andric   if (log) {
5745ffd83dbSDimitry Andric     StreamString s;
5755ffd83dbSDimitry Andric     s.Printf("ABISysV_mips::PrepareTrivialCall (tid = 0x%" PRIx64
5765ffd83dbSDimitry Andric              ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
5775ffd83dbSDimitry Andric              ", return_addr = 0x%" PRIx64,
5785ffd83dbSDimitry Andric              thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
5795ffd83dbSDimitry Andric              (uint64_t)return_addr);
5805ffd83dbSDimitry Andric 
5815ffd83dbSDimitry Andric     for (size_t i = 0; i < args.size(); ++i)
5825ffd83dbSDimitry Andric       s.Printf(", arg%zd = 0x%" PRIx64, i + 1, args[i]);
5835ffd83dbSDimitry Andric     s.PutCString(")");
5845ffd83dbSDimitry Andric     log->PutString(s.GetString());
5855ffd83dbSDimitry Andric   }
5865ffd83dbSDimitry Andric 
5875ffd83dbSDimitry Andric   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
5885ffd83dbSDimitry Andric   if (!reg_ctx)
5895ffd83dbSDimitry Andric     return false;
5905ffd83dbSDimitry Andric 
5915ffd83dbSDimitry Andric   const RegisterInfo *reg_info = nullptr;
5925ffd83dbSDimitry Andric 
5935ffd83dbSDimitry Andric   RegisterValue reg_value;
5945ffd83dbSDimitry Andric 
5955ffd83dbSDimitry Andric   // Argument registers
5965ffd83dbSDimitry Andric   const char *reg_names[] = {"r4", "r5", "r6", "r7"};
5975ffd83dbSDimitry Andric 
5985ffd83dbSDimitry Andric   llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
5995ffd83dbSDimitry Andric 
6005ffd83dbSDimitry Andric   // Write arguments to registers
601bdd1243dSDimitry Andric   for (size_t i = 0; i < std::size(reg_names); ++i) {
6025ffd83dbSDimitry Andric     if (ai == ae)
6035ffd83dbSDimitry Andric       break;
6045ffd83dbSDimitry Andric 
6055ffd83dbSDimitry Andric     reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
6065ffd83dbSDimitry Andric                                         LLDB_REGNUM_GENERIC_ARG1 + i);
6075ffd83dbSDimitry Andric     LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
6085ffd83dbSDimitry Andric               args[i], reg_info->name);
6095ffd83dbSDimitry Andric 
6105ffd83dbSDimitry Andric     if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
6115ffd83dbSDimitry Andric       return false;
6125ffd83dbSDimitry Andric 
6135ffd83dbSDimitry Andric     ++ai;
6145ffd83dbSDimitry Andric   }
6155ffd83dbSDimitry Andric 
6165ffd83dbSDimitry Andric   // If we have more than 4 arguments --Spill onto the stack
6175ffd83dbSDimitry Andric   if (ai != ae) {
6185ffd83dbSDimitry Andric     // No of arguments to go on stack
6195ffd83dbSDimitry Andric     size_t num_stack_regs = args.size();
6205ffd83dbSDimitry Andric 
6215ffd83dbSDimitry Andric     // Allocate needed space for args on the stack
6225ffd83dbSDimitry Andric     sp -= (num_stack_regs * 4);
6235ffd83dbSDimitry Andric 
6245ffd83dbSDimitry Andric     // Keep the stack 8 byte aligned
6255ffd83dbSDimitry Andric     sp &= ~(8ull - 1ull);
6265ffd83dbSDimitry Andric 
6275ffd83dbSDimitry Andric     // just using arg1 to get the right size
6285ffd83dbSDimitry Andric     const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
6295ffd83dbSDimitry Andric         eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
6305ffd83dbSDimitry Andric 
6315ffd83dbSDimitry Andric     addr_t arg_pos = sp + 16;
6325ffd83dbSDimitry Andric 
6335ffd83dbSDimitry Andric     size_t i = 4;
6345ffd83dbSDimitry Andric     for (; ai != ae; ++ai) {
6355ffd83dbSDimitry Andric       reg_value.SetUInt32(*ai);
6365ffd83dbSDimitry Andric       LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") at  0x%" PRIx64 "",
6375ffd83dbSDimitry Andric                 i + 1, args[i], arg_pos);
6385ffd83dbSDimitry Andric 
6395ffd83dbSDimitry Andric       if (reg_ctx
6405ffd83dbSDimitry Andric               ->WriteRegisterValueToMemory(reg_info, arg_pos,
6415ffd83dbSDimitry Andric                                            reg_info->byte_size, reg_value)
6425ffd83dbSDimitry Andric               .Fail())
6435ffd83dbSDimitry Andric         return false;
6445ffd83dbSDimitry Andric       arg_pos += reg_info->byte_size;
6455ffd83dbSDimitry Andric       i++;
6465ffd83dbSDimitry Andric     }
6475ffd83dbSDimitry Andric   }
6485ffd83dbSDimitry Andric 
6495ffd83dbSDimitry Andric   Status error;
6505ffd83dbSDimitry Andric   const RegisterInfo *pc_reg_info =
6515ffd83dbSDimitry Andric       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
6525ffd83dbSDimitry Andric   const RegisterInfo *sp_reg_info =
6535ffd83dbSDimitry Andric       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
6545ffd83dbSDimitry Andric   const RegisterInfo *ra_reg_info =
6555ffd83dbSDimitry Andric       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
6565ffd83dbSDimitry Andric   const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
6575ffd83dbSDimitry Andric   const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
6585ffd83dbSDimitry Andric 
6595ffd83dbSDimitry Andric   LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0);
6605ffd83dbSDimitry Andric 
6615ffd83dbSDimitry Andric   /* Write r0 with 0, in case we are stopped in syscall,
6625ffd83dbSDimitry Andric    * such setting prevents automatic decrement of the PC.
6635ffd83dbSDimitry Andric    * This clears the bug 23659 for MIPS.
6645ffd83dbSDimitry Andric   */
6655ffd83dbSDimitry Andric   if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0))
6665ffd83dbSDimitry Andric     return false;
6675ffd83dbSDimitry Andric 
6685ffd83dbSDimitry Andric   LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
6695ffd83dbSDimitry Andric 
6705ffd83dbSDimitry Andric   // Set "sp" to the requested value
6715ffd83dbSDimitry Andric   if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
6725ffd83dbSDimitry Andric     return false;
6735ffd83dbSDimitry Andric 
6745ffd83dbSDimitry Andric   LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
6755ffd83dbSDimitry Andric 
6765ffd83dbSDimitry Andric   // Set "ra" to the return address
6775ffd83dbSDimitry Andric   if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
6785ffd83dbSDimitry Andric     return false;
6795ffd83dbSDimitry Andric 
6805ffd83dbSDimitry Andric   LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
6815ffd83dbSDimitry Andric 
6825ffd83dbSDimitry Andric   // Set pc to the address of the called function.
6835ffd83dbSDimitry Andric   if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
6845ffd83dbSDimitry Andric     return false;
6855ffd83dbSDimitry Andric 
6865ffd83dbSDimitry Andric   LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
6875ffd83dbSDimitry Andric 
6885ffd83dbSDimitry Andric   // All callers of position independent functions must place the address of
6895ffd83dbSDimitry Andric   // the called function in t9 (r25)
6905ffd83dbSDimitry Andric   if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr))
6915ffd83dbSDimitry Andric     return false;
6925ffd83dbSDimitry Andric 
6935ffd83dbSDimitry Andric   return true;
6945ffd83dbSDimitry Andric }
6955ffd83dbSDimitry Andric 
GetArgumentValues(Thread & thread,ValueList & values) const6965ffd83dbSDimitry Andric bool ABISysV_mips::GetArgumentValues(Thread &thread, ValueList &values) const {
6975ffd83dbSDimitry Andric   return false;
6985ffd83dbSDimitry Andric }
6995ffd83dbSDimitry Andric 
SetReturnValueObject(lldb::StackFrameSP & frame_sp,lldb::ValueObjectSP & new_value_sp)7005ffd83dbSDimitry Andric Status ABISysV_mips::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
7015ffd83dbSDimitry Andric                                           lldb::ValueObjectSP &new_value_sp) {
7025ffd83dbSDimitry Andric   Status error;
7035ffd83dbSDimitry Andric   if (!new_value_sp) {
7045ffd83dbSDimitry Andric     error.SetErrorString("Empty value object for return value.");
7055ffd83dbSDimitry Andric     return error;
7065ffd83dbSDimitry Andric   }
7075ffd83dbSDimitry Andric 
7085ffd83dbSDimitry Andric   CompilerType compiler_type = new_value_sp->GetCompilerType();
7095ffd83dbSDimitry Andric   if (!compiler_type) {
7105ffd83dbSDimitry Andric     error.SetErrorString("Null clang type for return value.");
7115ffd83dbSDimitry Andric     return error;
7125ffd83dbSDimitry Andric   }
7135ffd83dbSDimitry Andric 
7145ffd83dbSDimitry Andric   Thread *thread = frame_sp->GetThread().get();
7155ffd83dbSDimitry Andric 
7165ffd83dbSDimitry Andric   bool is_signed;
7175ffd83dbSDimitry Andric   uint32_t count;
7185ffd83dbSDimitry Andric   bool is_complex;
7195ffd83dbSDimitry Andric 
7205ffd83dbSDimitry Andric   RegisterContext *reg_ctx = thread->GetRegisterContext().get();
7215ffd83dbSDimitry Andric 
7225ffd83dbSDimitry Andric   bool set_it_simple = false;
7235ffd83dbSDimitry Andric   if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
7245ffd83dbSDimitry Andric       compiler_type.IsPointerType()) {
7255ffd83dbSDimitry Andric     DataExtractor data;
7265ffd83dbSDimitry Andric     Status data_error;
7275ffd83dbSDimitry Andric     size_t num_bytes = new_value_sp->GetData(data, data_error);
7285ffd83dbSDimitry Andric     if (data_error.Fail()) {
7295ffd83dbSDimitry Andric       error.SetErrorStringWithFormat(
7305ffd83dbSDimitry Andric           "Couldn't convert return value to raw data: %s",
7315ffd83dbSDimitry Andric           data_error.AsCString());
7325ffd83dbSDimitry Andric       return error;
7335ffd83dbSDimitry Andric     }
7345ffd83dbSDimitry Andric 
7355ffd83dbSDimitry Andric     lldb::offset_t offset = 0;
7365ffd83dbSDimitry Andric     if (num_bytes <= 8) {
7375ffd83dbSDimitry Andric       const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
7385ffd83dbSDimitry Andric       if (num_bytes <= 4) {
7395ffd83dbSDimitry Andric         uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
7405ffd83dbSDimitry Andric 
7415ffd83dbSDimitry Andric         if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value))
7425ffd83dbSDimitry Andric           set_it_simple = true;
7435ffd83dbSDimitry Andric       } else {
7445ffd83dbSDimitry Andric         uint32_t raw_value = data.GetMaxU32(&offset, 4);
7455ffd83dbSDimitry Andric 
7465ffd83dbSDimitry Andric         if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) {
7475ffd83dbSDimitry Andric           const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
7485ffd83dbSDimitry Andric           uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
7495ffd83dbSDimitry Andric 
7505ffd83dbSDimitry Andric           if (reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value))
7515ffd83dbSDimitry Andric             set_it_simple = true;
7525ffd83dbSDimitry Andric         }
7535ffd83dbSDimitry Andric       }
7545ffd83dbSDimitry Andric     } else {
7555ffd83dbSDimitry Andric       error.SetErrorString("We don't support returning longer than 64 bit "
7565ffd83dbSDimitry Andric                            "integer values at present.");
7575ffd83dbSDimitry Andric     }
7585ffd83dbSDimitry Andric   } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
7595ffd83dbSDimitry Andric     if (is_complex)
7605ffd83dbSDimitry Andric       error.SetErrorString(
7615ffd83dbSDimitry Andric           "We don't support returning complex values at present");
7625ffd83dbSDimitry Andric     else
7635ffd83dbSDimitry Andric       error.SetErrorString(
7645ffd83dbSDimitry Andric           "We don't support returning float values at present");
7655ffd83dbSDimitry Andric   }
7665ffd83dbSDimitry Andric 
7675ffd83dbSDimitry Andric   if (!set_it_simple)
7685ffd83dbSDimitry Andric     error.SetErrorString(
7695ffd83dbSDimitry Andric         "We only support setting simple integer return types at present.");
7705ffd83dbSDimitry Andric 
7715ffd83dbSDimitry Andric   return error;
7725ffd83dbSDimitry Andric }
7735ffd83dbSDimitry Andric 
GetReturnValueObjectSimple(Thread & thread,CompilerType & return_compiler_type) const7745ffd83dbSDimitry Andric ValueObjectSP ABISysV_mips::GetReturnValueObjectSimple(
7755ffd83dbSDimitry Andric     Thread &thread, CompilerType &return_compiler_type) const {
7765ffd83dbSDimitry Andric   ValueObjectSP return_valobj_sp;
7775ffd83dbSDimitry Andric   return return_valobj_sp;
7785ffd83dbSDimitry Andric }
7795ffd83dbSDimitry Andric 
GetReturnValueObjectImpl(Thread & thread,CompilerType & return_compiler_type) const7805ffd83dbSDimitry Andric ValueObjectSP ABISysV_mips::GetReturnValueObjectImpl(
7815ffd83dbSDimitry Andric     Thread &thread, CompilerType &return_compiler_type) const {
7825ffd83dbSDimitry Andric   ValueObjectSP return_valobj_sp;
7835ffd83dbSDimitry Andric   Value value;
7845ffd83dbSDimitry Andric 
7855ffd83dbSDimitry Andric   if (!return_compiler_type)
7865ffd83dbSDimitry Andric     return return_valobj_sp;
7875ffd83dbSDimitry Andric 
7885ffd83dbSDimitry Andric   ExecutionContext exe_ctx(thread.shared_from_this());
7895ffd83dbSDimitry Andric   if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
7905ffd83dbSDimitry Andric     return return_valobj_sp;
7915ffd83dbSDimitry Andric 
7925ffd83dbSDimitry Andric   Target *target = exe_ctx.GetTargetPtr();
7935ffd83dbSDimitry Andric   const ArchSpec target_arch = target->GetArchitecture();
7945ffd83dbSDimitry Andric   ByteOrder target_byte_order = target_arch.GetByteOrder();
7955ffd83dbSDimitry Andric   value.SetCompilerType(return_compiler_type);
7965ffd83dbSDimitry Andric   uint32_t fp_flag =
7975ffd83dbSDimitry Andric       target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask;
7985ffd83dbSDimitry Andric 
7995ffd83dbSDimitry Andric   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
8005ffd83dbSDimitry Andric   if (!reg_ctx)
8015ffd83dbSDimitry Andric     return return_valobj_sp;
8025ffd83dbSDimitry Andric 
8035ffd83dbSDimitry Andric   bool is_signed = false;
8045ffd83dbSDimitry Andric   bool is_complex = false;
8055ffd83dbSDimitry Andric   uint32_t count = 0;
8065ffd83dbSDimitry Andric 
8075ffd83dbSDimitry Andric   // In MIPS register "r2" (v0) holds the integer function return values
8085ffd83dbSDimitry Andric   const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoByName("r2", 0);
809bdd1243dSDimitry Andric   std::optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread);
8105ffd83dbSDimitry Andric   if (!bit_width)
8115ffd83dbSDimitry Andric     return return_valobj_sp;
8125ffd83dbSDimitry Andric   if (return_compiler_type.IsIntegerOrEnumerationType(is_signed)) {
8135ffd83dbSDimitry Andric     switch (*bit_width) {
8145ffd83dbSDimitry Andric     default:
8155ffd83dbSDimitry Andric       return return_valobj_sp;
8165ffd83dbSDimitry Andric     case 64: {
8175ffd83dbSDimitry Andric       const RegisterInfo *r3_reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
8185ffd83dbSDimitry Andric       uint64_t raw_value;
8195ffd83dbSDimitry Andric       raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX;
8205ffd83dbSDimitry Andric       raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0) &
8215ffd83dbSDimitry Andric                                UINT32_MAX))
8225ffd83dbSDimitry Andric                    << 32;
8235ffd83dbSDimitry Andric       if (is_signed)
8245ffd83dbSDimitry Andric         value.GetScalar() = (int64_t)raw_value;
8255ffd83dbSDimitry Andric       else
8265ffd83dbSDimitry Andric         value.GetScalar() = (uint64_t)raw_value;
8275ffd83dbSDimitry Andric     } break;
8285ffd83dbSDimitry Andric     case 32:
8295ffd83dbSDimitry Andric       if (is_signed)
8305ffd83dbSDimitry Andric         value.GetScalar() = (int32_t)(
8315ffd83dbSDimitry Andric             reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX);
8325ffd83dbSDimitry Andric       else
8335ffd83dbSDimitry Andric         value.GetScalar() = (uint32_t)(
8345ffd83dbSDimitry Andric             reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX);
8355ffd83dbSDimitry Andric       break;
8365ffd83dbSDimitry Andric     case 16:
8375ffd83dbSDimitry Andric       if (is_signed)
8385ffd83dbSDimitry Andric         value.GetScalar() = (int16_t)(
8395ffd83dbSDimitry Andric             reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX);
8405ffd83dbSDimitry Andric       else
8415ffd83dbSDimitry Andric         value.GetScalar() = (uint16_t)(
8425ffd83dbSDimitry Andric             reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX);
8435ffd83dbSDimitry Andric       break;
8445ffd83dbSDimitry Andric     case 8:
8455ffd83dbSDimitry Andric       if (is_signed)
8465ffd83dbSDimitry Andric         value.GetScalar() = (int8_t)(
8475ffd83dbSDimitry Andric             reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX);
8485ffd83dbSDimitry Andric       else
8495ffd83dbSDimitry Andric         value.GetScalar() = (uint8_t)(
8505ffd83dbSDimitry Andric             reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX);
8515ffd83dbSDimitry Andric       break;
8525ffd83dbSDimitry Andric     }
8535ffd83dbSDimitry Andric   } else if (return_compiler_type.IsPointerType()) {
8545ffd83dbSDimitry Andric     uint32_t ptr =
8555ffd83dbSDimitry Andric         thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_reg_info, 0) &
8565ffd83dbSDimitry Andric         UINT32_MAX;
8575ffd83dbSDimitry Andric     value.GetScalar() = ptr;
8585ffd83dbSDimitry Andric   } else if (return_compiler_type.IsAggregateType()) {
8595ffd83dbSDimitry Andric     // Structure/Vector is always passed in memory and pointer to that memory
8605ffd83dbSDimitry Andric     // is passed in r2.
8615ffd83dbSDimitry Andric     uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(
8625ffd83dbSDimitry Andric         reg_ctx->GetRegisterInfoByName("r2", 0), 0);
8635ffd83dbSDimitry Andric     // We have got the address. Create a memory object out of it
8645ffd83dbSDimitry Andric     return_valobj_sp = ValueObjectMemory::Create(
8655ffd83dbSDimitry Andric         &thread, "", Address(mem_address, nullptr), return_compiler_type);
8665ffd83dbSDimitry Andric     return return_valobj_sp;
8675ffd83dbSDimitry Andric   } else if (return_compiler_type.IsFloatingPointType(count, is_complex)) {
8685ffd83dbSDimitry Andric     if (IsSoftFloat(fp_flag)) {
8695ffd83dbSDimitry Andric       uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0);
8705ffd83dbSDimitry Andric       if (count != 1 && is_complex)
8715ffd83dbSDimitry Andric         return return_valobj_sp;
8725ffd83dbSDimitry Andric       switch (*bit_width) {
8735ffd83dbSDimitry Andric       default:
8745ffd83dbSDimitry Andric         return return_valobj_sp;
8755ffd83dbSDimitry Andric       case 32:
876bdd1243dSDimitry Andric         static_assert(sizeof(float) == sizeof(uint32_t));
8775ffd83dbSDimitry Andric         value.GetScalar() = *((float *)(&raw_value));
8785ffd83dbSDimitry Andric         break;
8795ffd83dbSDimitry Andric       case 64:
880bdd1243dSDimitry Andric         static_assert(sizeof(double) == sizeof(uint64_t));
8815ffd83dbSDimitry Andric         const RegisterInfo *r3_reg_info =
8825ffd83dbSDimitry Andric             reg_ctx->GetRegisterInfoByName("r3", 0);
8835ffd83dbSDimitry Andric         if (target_byte_order == eByteOrderLittle)
8845ffd83dbSDimitry Andric           raw_value =
8855ffd83dbSDimitry Andric               ((reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0)) << 32) |
8865ffd83dbSDimitry Andric               raw_value;
8875ffd83dbSDimitry Andric         else
8885ffd83dbSDimitry Andric           raw_value = (raw_value << 32) |
8895ffd83dbSDimitry Andric                       reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0);
8905ffd83dbSDimitry Andric         value.GetScalar() = *((double *)(&raw_value));
8915ffd83dbSDimitry Andric         break;
8925ffd83dbSDimitry Andric       }
8935ffd83dbSDimitry Andric     }
8945ffd83dbSDimitry Andric 
8955ffd83dbSDimitry Andric     else {
8965ffd83dbSDimitry Andric       const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
8975ffd83dbSDimitry Andric       RegisterValue f0_value;
8985ffd83dbSDimitry Andric       DataExtractor f0_data;
8995ffd83dbSDimitry Andric       reg_ctx->ReadRegister(f0_info, f0_value);
9005ffd83dbSDimitry Andric       f0_value.GetData(f0_data);
9015ffd83dbSDimitry Andric       lldb::offset_t offset = 0;
9025ffd83dbSDimitry Andric 
9035ffd83dbSDimitry Andric       if (count == 1 && !is_complex) {
9045ffd83dbSDimitry Andric         switch (*bit_width) {
9055ffd83dbSDimitry Andric         default:
9065ffd83dbSDimitry Andric           return return_valobj_sp;
9075ffd83dbSDimitry Andric         case 64: {
908bdd1243dSDimitry Andric           static_assert(sizeof(double) == sizeof(uint64_t));
9095ffd83dbSDimitry Andric           const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
9105ffd83dbSDimitry Andric           RegisterValue f1_value;
9115ffd83dbSDimitry Andric           DataExtractor f1_data;
9125ffd83dbSDimitry Andric           reg_ctx->ReadRegister(f1_info, f1_value);
9135ffd83dbSDimitry Andric           DataExtractor *copy_from_extractor = nullptr;
91481ad6265SDimitry Andric           WritableDataBufferSP data_sp(new DataBufferHeap(8, 0));
9155ffd83dbSDimitry Andric           DataExtractor return_ext(
9165ffd83dbSDimitry Andric               data_sp, target_byte_order,
9175ffd83dbSDimitry Andric               target->GetArchitecture().GetAddressByteSize());
9185ffd83dbSDimitry Andric 
9195ffd83dbSDimitry Andric           if (target_byte_order == eByteOrderLittle) {
9205ffd83dbSDimitry Andric             copy_from_extractor = &f0_data;
9215ffd83dbSDimitry Andric             copy_from_extractor->CopyByteOrderedData(
9225ffd83dbSDimitry Andric                 offset, 4, data_sp->GetBytes(), 4, target_byte_order);
9235ffd83dbSDimitry Andric             f1_value.GetData(f1_data);
9245ffd83dbSDimitry Andric             copy_from_extractor = &f1_data;
9255ffd83dbSDimitry Andric             copy_from_extractor->CopyByteOrderedData(
9265ffd83dbSDimitry Andric                 offset, 4, data_sp->GetBytes() + 4, 4, target_byte_order);
9275ffd83dbSDimitry Andric           } else {
9285ffd83dbSDimitry Andric             copy_from_extractor = &f0_data;
9295ffd83dbSDimitry Andric             copy_from_extractor->CopyByteOrderedData(
9305ffd83dbSDimitry Andric                 offset, 4, data_sp->GetBytes() + 4, 4, target_byte_order);
9315ffd83dbSDimitry Andric             f1_value.GetData(f1_data);
9325ffd83dbSDimitry Andric             copy_from_extractor = &f1_data;
9335ffd83dbSDimitry Andric             copy_from_extractor->CopyByteOrderedData(
9345ffd83dbSDimitry Andric                 offset, 4, data_sp->GetBytes(), 4, target_byte_order);
9355ffd83dbSDimitry Andric           }
9365ffd83dbSDimitry Andric           value.GetScalar() = (double)return_ext.GetDouble(&offset);
9375ffd83dbSDimitry Andric           break;
9385ffd83dbSDimitry Andric         }
9395ffd83dbSDimitry Andric         case 32: {
940bdd1243dSDimitry Andric           static_assert(sizeof(float) == sizeof(uint32_t));
9415ffd83dbSDimitry Andric           value.GetScalar() = (float)f0_data.GetFloat(&offset);
9425ffd83dbSDimitry Andric           break;
9435ffd83dbSDimitry Andric         }
9445ffd83dbSDimitry Andric         }
9455ffd83dbSDimitry Andric       } else {
9465ffd83dbSDimitry Andric         // not handled yet
9475ffd83dbSDimitry Andric         return return_valobj_sp;
9485ffd83dbSDimitry Andric       }
9495ffd83dbSDimitry Andric     }
9505ffd83dbSDimitry Andric   } else {
9515ffd83dbSDimitry Andric     // not handled yet
9525ffd83dbSDimitry Andric     return return_valobj_sp;
9535ffd83dbSDimitry Andric   }
9545ffd83dbSDimitry Andric 
9555ffd83dbSDimitry Andric   // If we get here, we have a valid Value, so make our ValueObject out of it:
9565ffd83dbSDimitry Andric 
9575ffd83dbSDimitry Andric   return_valobj_sp = ValueObjectConstResult::Create(
9585ffd83dbSDimitry Andric       thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
9595ffd83dbSDimitry Andric   return return_valobj_sp;
9605ffd83dbSDimitry Andric }
9615ffd83dbSDimitry Andric 
CreateFunctionEntryUnwindPlan(UnwindPlan & unwind_plan)9625ffd83dbSDimitry Andric bool ABISysV_mips::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
9635ffd83dbSDimitry Andric   unwind_plan.Clear();
9645ffd83dbSDimitry Andric   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
9655ffd83dbSDimitry Andric 
9665ffd83dbSDimitry Andric   UnwindPlan::RowSP row(new UnwindPlan::Row);
9675ffd83dbSDimitry Andric 
9685ffd83dbSDimitry Andric   // Our Call Frame Address is the stack pointer value
9695ffd83dbSDimitry Andric   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
9705ffd83dbSDimitry Andric 
9715ffd83dbSDimitry Andric   // The previous PC is in the RA
9725ffd83dbSDimitry Andric   row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
9735ffd83dbSDimitry Andric   unwind_plan.AppendRow(row);
9745ffd83dbSDimitry Andric 
9755ffd83dbSDimitry Andric   // All other registers are the same.
9765ffd83dbSDimitry Andric 
9775ffd83dbSDimitry Andric   unwind_plan.SetSourceName("mips at-func-entry default");
9785ffd83dbSDimitry Andric   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
9795ffd83dbSDimitry Andric   unwind_plan.SetReturnAddressRegister(dwarf_r31);
9805ffd83dbSDimitry Andric   return true;
9815ffd83dbSDimitry Andric }
9825ffd83dbSDimitry Andric 
CreateDefaultUnwindPlan(UnwindPlan & unwind_plan)9835ffd83dbSDimitry Andric bool ABISysV_mips::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
9845ffd83dbSDimitry Andric   unwind_plan.Clear();
9855ffd83dbSDimitry Andric   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
9865ffd83dbSDimitry Andric 
9875ffd83dbSDimitry Andric   UnwindPlan::RowSP row(new UnwindPlan::Row);
9885ffd83dbSDimitry Andric 
989fe6060f1SDimitry Andric   row->SetUnspecifiedRegistersAreUndefined(true);
9905ffd83dbSDimitry Andric   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
9915ffd83dbSDimitry Andric 
9925ffd83dbSDimitry Andric   row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
9935ffd83dbSDimitry Andric 
9945ffd83dbSDimitry Andric   unwind_plan.AppendRow(row);
9955ffd83dbSDimitry Andric   unwind_plan.SetSourceName("mips default unwind plan");
9965ffd83dbSDimitry Andric   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
9975ffd83dbSDimitry Andric   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
9985ffd83dbSDimitry Andric   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
9995ffd83dbSDimitry Andric   return true;
10005ffd83dbSDimitry Andric }
10015ffd83dbSDimitry Andric 
RegisterIsVolatile(const RegisterInfo * reg_info)10025ffd83dbSDimitry Andric bool ABISysV_mips::RegisterIsVolatile(const RegisterInfo *reg_info) {
10035ffd83dbSDimitry Andric   return !RegisterIsCalleeSaved(reg_info);
10045ffd83dbSDimitry Andric }
10055ffd83dbSDimitry Andric 
IsSoftFloat(uint32_t fp_flags) const10065ffd83dbSDimitry Andric bool ABISysV_mips::IsSoftFloat(uint32_t fp_flags) const {
10075ffd83dbSDimitry Andric   return (fp_flags == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
10085ffd83dbSDimitry Andric }
10095ffd83dbSDimitry Andric 
RegisterIsCalleeSaved(const RegisterInfo * reg_info)10105ffd83dbSDimitry Andric bool ABISysV_mips::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
10115ffd83dbSDimitry Andric   if (reg_info) {
10125ffd83dbSDimitry Andric     // Preserved registers are :
10135ffd83dbSDimitry Andric     // r16-r23, r28, r29, r30, r31
10145ffd83dbSDimitry Andric     const char *name = reg_info->name;
10155ffd83dbSDimitry Andric 
10165ffd83dbSDimitry Andric     if (name[0] == 'r') {
10175ffd83dbSDimitry Andric       switch (name[1]) {
10185ffd83dbSDimitry Andric       case '1':
10195ffd83dbSDimitry Andric         if (name[2] == '6' || name[2] == '7' || name[2] == '8' ||
10205ffd83dbSDimitry Andric             name[2] == '9') // r16-r19
10215ffd83dbSDimitry Andric           return name[3] == '\0';
10225ffd83dbSDimitry Andric         break;
10235ffd83dbSDimitry Andric       case '2':
10245ffd83dbSDimitry Andric         if (name[2] == '0' || name[2] == '1' || name[2] == '2' ||
10255ffd83dbSDimitry Andric             name[2] == '3'                       // r20-r23
10265ffd83dbSDimitry Andric             || name[2] == '8' || name[2] == '9') // r28 and r29
10275ffd83dbSDimitry Andric           return name[3] == '\0';
10285ffd83dbSDimitry Andric         break;
10295ffd83dbSDimitry Andric       case '3':
10305ffd83dbSDimitry Andric         if (name[2] == '0' || name[2] == '1') // r30 and r31
10315ffd83dbSDimitry Andric           return name[3] == '\0';
10325ffd83dbSDimitry Andric         break;
10335ffd83dbSDimitry Andric       }
10345ffd83dbSDimitry Andric 
10355ffd83dbSDimitry Andric       if (name[0] == 'g' && name[1] == 'p' && name[2] == '\0') // gp (r28)
10365ffd83dbSDimitry Andric         return true;
10375ffd83dbSDimitry Andric       if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp (r29)
10385ffd83dbSDimitry Andric         return true;
10395ffd83dbSDimitry Andric       if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp (r30)
10405ffd83dbSDimitry Andric         return true;
10415ffd83dbSDimitry Andric       if (name[0] == 'r' && name[1] == 'a' && name[2] == '\0') // ra (r31)
10425ffd83dbSDimitry Andric         return true;
10435ffd83dbSDimitry Andric     }
10445ffd83dbSDimitry Andric   }
10455ffd83dbSDimitry Andric   return false;
10465ffd83dbSDimitry Andric }
10475ffd83dbSDimitry Andric 
Initialize()10485ffd83dbSDimitry Andric void ABISysV_mips::Initialize() {
10495ffd83dbSDimitry Andric   PluginManager::RegisterPlugin(
10505ffd83dbSDimitry Andric       GetPluginNameStatic(), "System V ABI for mips targets", CreateInstance);
10515ffd83dbSDimitry Andric }
10525ffd83dbSDimitry Andric 
Terminate()10535ffd83dbSDimitry Andric void ABISysV_mips::Terminate() {
10545ffd83dbSDimitry Andric   PluginManager::UnregisterPlugin(CreateInstance);
10555ffd83dbSDimitry Andric }
1056