Lors de la compilation ce code C++:GCC a généré un Misaligned "LDRD" Instruction
#include "../SM64DS_2.h"
//@021026a0, hooks: 0x020bddb8, 0x020bde0c
void CancelPowerups(Player& player)
{
if(player.isFreezeFramePeach)
{
player.isFreezeFramePeach = false;
player.EndMusic(0x33);
}
if(player.isDashyToad)
{
player.isDashyToad = false;
player.EndMusic(0x33);
}
}
//hook: 0x020b98f8
void EnableFreezeFramePeach(Player& player)
{
//TODO: Show message on first use
player.isFreezeFramePeach = true;
player.flowerPowerTimer = 600;
player.SetMusic(0x33);
}
//hook: 0x020b9904
void EnableDashyToad(Player& player)
{
//TODO: Show message on first use
player.isDashyToad = true;
player.flowerPowerTimer = 600;
player.SetMusic(0x33);
}
//hook: 0x020e4f10
void WorkDashyToadPart1(Player& player)
{
//TODO: Deal with speed of walking animation
if(player.isDashyToad)
{
player.horzSpeed /= 2;
player.isSpeedHalfed = true;
if(player.walkOnWaterTimer == 61)
++player.walkOnWaterTimer;
}
}
//hook: 0x020e52e8
void WorkDashyToadPart2(Player& player)
{
if(player.isSpeedHalfed)
{
player.horzSpeed *= 2;
player.isSpeedHalfed = false;
player.dashyToadParticleSysID = Particle::System::New(player.dashyToadParticleSysID,
0x4a,
player.pos.x,
player.pos.y + Fix12i(72),
player.pos.z,
nullptr,
nullptr);
}
}
avec les indicateurs suivants pour gcc
arm-none-eabi-g++ -MMD -MP -MF /c/Users/Joshua/Documents/desmume-0.9.11-win64/SM64DSe/SM64DSe/ASMPatchTemplate/build/PeachToadAbilities.d -g -Wall -O2 -march=armv5te -mtune=arm946e-s -fomit-frame-pointer -ffast-math -iquote /c/Users/Joshua/Documents/desmume-0.9.11-win64/SM64DSe/SM64DSe/ASMPatchTemplate/include -I/c/devkitPro/libnds/include -I/c/devkitPro/devkitARM/include -I/c/devkitPro/devkitARM/arm-none-eabi/include -I/c/Users/Joshua/Documents/desmume-0.9.11-win64/SM64DSe/SM64DSe/ASMPatchTemplate/build -DARM9 -nodefaultlibs -I. -fno-builtin -c --std=c++14 -fno-rtti -fno-exceptions -Wa,-adl=PeachToadAbilities.lst -c /c/Users/Joshua/Documents/desmume-0.9.11-win64/SM64DSe/SM64DSe/ASMPatchTemplate/source/C_PeachToadAbilities/PeachToadAbilities.cpp -o PeachToadAbilities.o
(Notez en particulier que l'architecture est ARMv5TE et la CPU est un ARM946E-S) l'ASM suivante est générée pour la dernière fonction:
push {r4, lr}
mov r4, r0
mov r1, #0x0
ldrd r2, [r4, #0x5c]
ldr ip, [r0, #0x98]
ldr r0, [r0, #0x280]
lsl ip, ip, #0x1
str ip, [r4, #0x98]
ldr ip, [r4, #0x64]
sub sp, sp, #0x10
strb r1, [r4, #0x27d]
add r3, r3, #0x48000
str r1, [sp, #0x8]
str r1, [sp, #0x4]
str ip, [sp]
mov r1, #0x4a
bl _ZN8Particle6System3NewEjj5Fix12IiES2_S2_PK11Vector3_16fPNS_8CallbackE
str r0, [r4, #0x280]
add sp, sp, #0x10
pop {r4, pc}
pour conte xt, ceci est un morceau d'un hack ROM d'un jeu Nintendo DS. La structure Player est alignée sur 4 octets, et au décalage 0x5C est la position du lecteur, qui est une structure de 3 Fix12 <int> (Un Fix12 <int> est une structure de 1 entier de 4 octets.). Le problème est que gcc génère une instruction "ldrd" qui ne peut pas être prouvée pour accéder à une adresse alignée de 8 octets (il ne devrait pas savoir où "player" est et en plus, 0x5C n'est pas un multiple de 8). . Les documentations ARM que j'ai regardées disent que pour ARMv5, le chargement d'un double mot mal aligné est un comportement indéfini. Cependant, aucun $ gba et DeSmuME ne supposent qu'un tel accès lorsque l'adresse est alignée sur 4 octets charge encore une valeur de 8 octets à partir de cette adresse. Est-ce correct pour ARMv5TE sur un CPU ARM946E-S? (Je n'ai pas testé cela sur un DS réel car je n'ai pas de carte flash.)
On dirait que l'exigence d'alignement à 8 octets a été supprimée des architectures d'armement ultérieures, et GCC n'honore pas l'ancienne exigence. Une solution possible consiste à désactiver ces instructions, en compilant uniquement pour ARMv5T? – NickJH