@@ -210,6 +210,7 @@ struct Function {
210210};
211211
212212bool conservative;
213+ bool n32;
213214
214215const uint8_t * text_section;
215216uint32_t text_section_len;
@@ -1967,26 +1968,38 @@ const char* r(uint32_t reg) {
19671968const char * wr (uint32_t reg) {
19681969 // clang-format off
19691970 static const char *regs[] = {
1970- " f0.w[0]" , " f0.w[1]" ,
1971- " f2.w[0]" , " f2.w[1]" ,
1972- " f4.w[0]" , " f4.w[1]" ,
1973- " f6.w[0]" , " f6.w[1]" ,
1974- " f8.w[0]" , " f8.w[1]" ,
1975- " f10.w[0]" , " f10.w[1]" ,
1976- " f12.w[0]" , " f12.w[1]" ,
1977- " f14.w[0]" , " f14.w[1]" ,
1978- " f16.w[0]" , " f16.w[1]" ,
1979- " f18.w[0]" , " f18.w[1]" ,
1980- " f20.w[0]" , " f20.w[1]" ,
1981- " f22.w[0]" , " f22.w[1]" ,
1982- " f24.w[0]" , " f24.w[1]" ,
1983- " f26.w[0]" , " f26.w[1]" ,
1984- " f28.w[0]" , " f28.w[1]" ,
1985- " f30.w[0]" , " f30.w[1]"
1971+ " f0.w[0]" , " f0.w[1] " , " f1.w[0] " , " f1 .w[1]" ,
1972+ " f2.w[0]" , " f2.w[1] " , " f3.w[0] " , " f3 .w[1]" ,
1973+ " f4.w[0]" , " f4.w[1] " , " f5.w[0] " , " f5 .w[1]" ,
1974+ " f6.w[0]" , " f6.w[1] " , " f7.w[0] " , " f7 .w[1]" ,
1975+ " f8.w[0]" , " f8.w[1] " , " f9.w[0] " , " f9 .w[1]" ,
1976+ " f10.w[0]" , " f10.w[1]" , " f11.w[0] " , " f11.w[1] " ,
1977+ " f12.w[0]" , " f12.w[1]" , " f13.w[0] " , " f13.w[1] " ,
1978+ " f14.w[0]" , " f14.w[1]" , " f15.w[0] " , " f15.w[1] " ,
1979+ " f16.w[0]" , " f16.w[1]" , " f17.w[0] " , " f17.w[1] " ,
1980+ " f18.w[0]" , " f18.w[1]" , " f19.w[0] " , " f19.w[1] " ,
1981+ " f20.w[0]" , " f20.w[1]" , " f21.w[0] " , " f21.w[1] " ,
1982+ " f22.w[0]" , " f22.w[1]" , " f23.w[0] " , " f23.w[1] " ,
1983+ " f24.w[0]" , " f24.w[1]" , " f25.w[0] " , " f25.w[1] " ,
1984+ " f26.w[0]" , " f26.w[1]" , " f27.w[0] " , " f27.w[1] " ,
1985+ " f28.w[0]" , " f28.w[1]" , " f29.w[0] " , " f29.w[1] " ,
1986+ " f30.w[0]" , " f30.w[1]" , " f31.w[0] " , " f31.w[1] " ,
19861987 };
19871988 // clang-format on
19881989
1989- size_t index = reg - (int )rabbitizer::Registers::Cpu::Cop1O32::COP1_O32_fv0;
1990+ size_t index;
1991+
1992+ if (n32) {
1993+ // In N32, all registers access the lower half of the register
1994+ index = reg * 2 ;
1995+ } else {
1996+ // In O32, odd registers alias the upper half of the previous register
1997+ if (reg % 2 == 0 ) {
1998+ index = reg * 2 ;
1999+ } else {
2000+ index = (reg - 1 ) * 2 + 1 ;
2001+ }
2002+ }
19902003
19912004 assert (index < std::size (regs));
19922005 return regs[index];
@@ -1995,26 +2008,38 @@ const char* wr(uint32_t reg) {
19952008const char * fr (uint32_t reg) {
19962009 // clang-format off
19972010 static const char *regs[] = {
1998- " f0.f[0]" , " f0.f[1]" ,
1999- " f2.f[0]" , " f2.f[1]" ,
2000- " f4.f[0]" , " f4.f[1]" ,
2001- " f6.f[0]" , " f6.f[1]" ,
2002- " f8.f[0]" , " f8.f[1]" ,
2003- " f10.f[0]" , " f10.f[1]" ,
2004- " f12.f[0]" , " f12.f[1]" ,
2005- " f14.f[0]" , " f14.f[1]" ,
2006- " f16.f[0]" , " f16.f[1]" ,
2007- " f18.f[0]" , " f18.f[1]" ,
2008- " f20.f[0]" , " f20.f[1]" ,
2009- " f22.f[0]" , " f22.f[1]" ,
2010- " f24.f[0]" , " f24.f[1]" ,
2011- " f26.f[0]" , " f26.f[1]" ,
2012- " f28.f[0]" , " f28.f[1]" ,
2013- " f30.f[0]" , " f30.f[1]" ,
2011+ " f0.f[0]" , " f0.f[1] " , " f1.f[0] " , " f1 .f[1]" ,
2012+ " f2.f[0]" , " f2.f[1] " , " f3.f[0] " , " f3 .f[1]" ,
2013+ " f4.f[0]" , " f4.f[1] " , " f5.f[0] " , " f5 .f[1]" ,
2014+ " f6.f[0]" , " f6.f[1] " , " f7.f[0] " , " f7 .f[1]" ,
2015+ " f8.f[0]" , " f8.f[1] " , " f9.f[0] " , " f9 .f[1]" ,
2016+ " f10.f[0]" , " f10.f[1]" , " f11.f[0] " , " f11.f[1] " ,
2017+ " f12.f[0]" , " f12.f[1]" , " f13.f[0] " , " f13.f[1] " ,
2018+ " f14.f[0]" , " f14.f[1]" , " f15.f[0] " , " f15.f[1] " ,
2019+ " f16.f[0]" , " f16.f[1]" , " f17.f[0] " , " f17.f[1] " ,
2020+ " f18.f[0]" , " f18.f[1]" , " f19.f[0] " , " f19.f[1] " ,
2021+ " f20.f[0]" , " f20.f[1]" , " f21.f[0] " , " f21.f[1] " ,
2022+ " f22.f[0]" , " f22.f[1]" , " f23.f[0] " , " f23.f[1] " ,
2023+ " f24.f[0]" , " f24.f[1]" , " f25.f[0] " , " f25.f[1] " ,
2024+ " f26.f[0]" , " f26.f[1]" , " f27.f[0] " , " f27.f[1] " ,
2025+ " f28.f[0]" , " f28.f[1]" , " f29.f[0] " , " f29.f[1] " ,
2026+ " f30.f[0]" , " f30.f[1]" , " f31.f[0] " , " f31.f[1] " ,
20142027 };
20152028 // clang-format on
20162029
2017- size_t index = reg - (int )rabbitizer::Registers::Cpu::Cop1O32::COP1_O32_fv0;
2030+ size_t index;
2031+
2032+ if (n32) {
2033+ // In N32, all registers access the lower half of the register
2034+ index = reg * 2 ;
2035+ } else {
2036+ // In O32, odd registers alias the upper half of the previous register
2037+ if (reg % 2 == 0 ) {
2038+ index = reg * 2 ;
2039+ } else {
2040+ index = (reg - 1 ) * 2 + 1 ;
2041+ }
2042+ }
20182043
20192044 assert (index < std::size (regs));
20202045 return regs[index];
@@ -2023,29 +2048,32 @@ const char* fr(uint32_t reg) {
20232048const char * dr (uint32_t reg) {
20242049 // clang-format off
20252050 static const char *regs[] = {
2026- " f0" ,
2027- " f2" ,
2028- " f4" ,
2029- " f6" ,
2030- " f8" ,
2031- " f10" ,
2032- " f12" ,
2033- " f14" ,
2034- " f16" ,
2035- " f18" ,
2036- " f20" ,
2037- " f22" ,
2038- " f24" ,
2039- " f26" ,
2040- " f28" ,
2041- " f30"
2051+ " f0" , " f1 " ,
2052+ " f2" , " f3 " ,
2053+ " f4" , " f5 " ,
2054+ " f6" , " f7 " ,
2055+ " f8" , " f9 " ,
2056+ " f10" , " f11 " ,
2057+ " f12" , " f13 " ,
2058+ " f14" , " f15 " ,
2059+ " f16" , " f17 " ,
2060+ " f18" , " f19 " ,
2061+ " f20" , " f21 " ,
2062+ " f22" , " f23 " ,
2063+ " f24" , " f25 " ,
2064+ " f26" , " f27 " ,
2065+ " f28" , " f29 " ,
2066+ " f30" , " f31 " ,
20422067 };
20432068 // clang-format on
20442069
2045- size_t index = reg - (int )rabbitizer::Registers::Cpu::Cop1O32::COP1_O32_fv0;
2070+ size_t index = reg;
2071+
2072+ if (!n32) {
2073+ // In O32, only even registers can be used as double registers
2074+ assert (reg % 2 == 0 );
2075+ }
20462076
2047- assert (index % 2 == 0 );
2048- index /= 2 ;
20492077 assert (index < std::size (regs));
20502078 return regs[index];
20512079}
@@ -3946,13 +3974,25 @@ void crashHandler(int sig) {
39463974#endif
39473975
39483976int main (int argc, char * argv[]) {
3949- const char * filename = argv[ 1 ] ;
3977+ int argi ;
39503978
3951- if ((argc > 2 ) && (strcmp (filename, " --conservative" ) == 0 )) {
3952- conservative = true ;
3953- filename = argv[2 ];
3979+ for (argi = 1 ; argi < argc; argi++) {
3980+ if (strcmp (argv[argi], " --conservative" ) == 0 ) {
3981+ conservative = true ;
3982+ } else if (strcmp (argv[argi], " --n32" ) == 0 ) {
3983+ n32 = true ;
3984+ } else {
3985+ break ;
3986+ }
3987+ }
3988+
3989+ if (argi != argc - 1 ) {
3990+ fprintf (stderr, " Usage: %s [--conservative] [--n32] <elf_file>\n " , argv[0 ]);
3991+ return 1 ;
39543992 }
39553993
3994+ const char * filename = argv[argi];
3995+
39563996#ifdef UNIX_PLATFORM
39573997 signal (SIGSEGV, crashHandler);
39583998 signal (SIGABRT, crashHandler);
0 commit comments