Skip to content

PS2: SN ProDG custom assembler issues #525

@IWILLCRAFT-M0d

Description

@IWILLCRAFT-M0d

First thing I want to say, excuse my ignorance over these compilers, assembler and assembly ignorance in advance, I hope everything here I will say doesn't get misunderstood, and thanks for the patient if this get solves.

As I have been reporting in the PS1/2 Decomp server and something pointed out by @Mc-muffin, SN compilers contains an alternative assembler to the one from GNU which can be enabled by using -snas in the compilation, this assembler is important as it runs into an issue related with GP_REL (you can see the bug in action here, by removing -snas from the compiler arguments) which is important to match and for some other issue I will explain below, the problem is that this assembler runs in many issues with Splat and the INCLUDE_ASM macro, just few of them I noticed are:

  • Neither macros.inc nor labels.inc works by default.
    • the usage of .size macro in glabel for some reason causes the assembler to suddenly crash without making any input about the error
    • the syntax of nonmatching macro is incompatible with the one that the assembler uses
  • The assembler bundled in the 2.0 release of the SN SDK it runs into not generating one pad in loops, something that both the default GAS and modern binutils do
    • Here it is an example, the game which this function was extracted from uses version 2.95.3 (v1.36), but the assembler bundled with that release is generating an additional pad which also get generated when building the compiler output to object https://decomp.me/scratch/4BvBh
    • This even affect INCLUDE_ASM macro
  • This assembler don't handle c1 macro instead it should be using cop1

There are two more I noticed, but didn't delve into them too much

  • The usage of vadda.xyz have the input register inverted. The only instance where I have seen this splats generates vadda.xyz ACC, $vf0, $vf1 in the assembly, however, this assembler swapped the register, and instead it needs to be vadda.xyz ACC, $vf1, $vf0 otherwise it will generate a mismatching result
  • Some instances where a GP_REL macro could be generated runs into issues. For now the only two instances I found of this bug are this:
    /* 8AE4 00107AE4 01000224 */  addiu      $2, $0, 0x1
    /* 8AE8 00107AE8 4000A397 */  lhu        $3, 0x40($29)
    /* 8AEC 00107AEC B48182AF */  sw         $2, (D_0044C8A4) /* gp_rel: (D_0044C8A4) */
    /* 8AF0 00107AF0 92EB83A7 */  sh         $3, (D_00453280 + 0x2) /* gp_rel: (D_00453280 + 0x2) */
    /* 8AF4 00107AF4 4500023C */  lui        $2, %hi(D_00453A80)
    /* 8E28 00107E28 01000224 */  addiu      $2, $0, 0x1
    /* 8E2C 00107E2C 2001A397 */  lhu        $3, 0x120($29)
    /* 8E30 00107E30 B88182AF */  sw         $2, (D_0044C8A8) /* gp_rel: (D_0044C8A8) */
    /* 8E34 00107E34 94EB83A7 */  sh         $3, (D_00453280 + 0x4) /* gp_rel: (D_00453280 + 0x4) */

In both of these instances the assembler has thrown me these errors:
Error : Assembler does not have AT register available, " sh $3, (D_00453280 + 0x2)"
Error : Assembler does not have AT register available, " sh $3, (D_00453280 + 0x4)"
And the process finishes with this message:
ee-gcc2953.exe: Internal compiler error: program ps2eeas got fatal signal 22
There may be more errors I missed, but I got stuck trying to solve this last issue

Not sure if this is just sad (because why these issues have to exist dang it) or fortunately (as there is only one public decomp which have run into this issue so still early to fix this before more decomps which runs into this issue join in) the only decomp for now running into all this issues (excepting the second one which is actually what I thought was related to the short loop bug I mentioned here, but I'm still setting up that one privately) is Dog's Life. The way that this assembler issue has been circumvented there is by marking as NON_MATCHING any function that requires the assembler to match and in matching build inserting the function using INCLUDE_ASM it compiles with GNU assembler instead, so this way progress keep being tracked, while it still able to make a building match, something like the latest PSX decomps, but if almost all functions that are actually matched were marked as NON_MATCHING until they finish a whole TU.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions