32 bit compare instruction?

Started by Deathwolf, August 08, 2011, 06:41:10 PM

Previous topic - Next topic

Deathwolf

Is there a 32 bit compare instruction?

Code:

cmpwi r4,0x02
bne- Default
lis r18,0x0000
ori r18,r18,0x000F
stw r18,4(r3)

Default:
stw r4,4(r3)


r4 has the value 00000002.

For some reason the code doesn't work....


Thanks for any help.
lolz

dcx2

#1
Immediates (the "i" in "cmpwi") are always 16-bit and are usually signed.

You can load a register with a 32-bit value and then use cmpw

However cmpwi r4,2 will set the equals bit when r4 = 00000002.  Perhaps you meant beq- instead of bne-?

EDIT:

btw, you should really use r12 instead of r18, unless you can prove r18 is safe.  remember, 0 does not mean safe.

EDIT2:

You could also re-use r4 instead of using r12, since the value in r4 is supposed to change anyway.

Also, the stw r18 will be over-written by the stw r4.  So the value you put in with stw r18 will never be there because the stw r4 overwrites it immediately.  Try this instead, assuming you meant bne-.

cmpwi r4,0x02
bne- Default
li r4,0x000F

Default:
stw r4,4(r3)

Deathwolf

Yeah if I activate the code without the compare and branch instruction, it works fine.

cmpwi r4,0x02 # compare r4 with 00000002
bne- Default   # if not equal, branch to Default
lis r18,0x0000  # write 0000000F to r18
ori r18,r18,0x000F
stw r18,4(r3)    # store r18 into r3 + 4 bytes.

Default:
stw r4,4(r3)  # original instruction.

Yep r18 is free. The code works with out the comparing thing.
lolz

dcx2

Prove to me that r18 is free.  Just because it worked and didn't crash this time doesn't make it free.  Just because it's 0 doesn't make it free.

Post the Copy Function for your hook and we'll see if it's actually free or not.

Deathwolf

Function:

[spoiler]807BC940:  1C04001C   mulli   r0,r4,28
807BC944:  3CC0809C   lis   r6,-32612
807BC948:  90830004   stw   r4,4(r3)
807BC94C:  38800000   li   r4,0
807BC950:  38C636A0   addi   r6,r6,13984
807BC954:  7CC60214   add   r6,r6,r0
807BC958:  80060008   lwz   r0,8(r6)
807BC95C:  90030008   stw   r0,8(r3)
807BC960:  90830018   stw   r4,24(r3)
807BC964:  98A30029   stb   r5,41(r3)
807BC968:  88060010   lbz   r0,16(r6)
807BC96C:  9803001C   stb   r0,28(r3)
807BC970:  90830020   stw   r4,32(r3)
807BC974:  90830024   stw   r4,36(r3)
807BC978:  4E800020   blr   
[/spoiler]
lolz

dcx2

#5
r18 is not free.  This function is a leaf function - no stack frame, which means the non-volatiles aren't stored.  For this particular function, r12-r7 are safe.  r11 is probably safe, but I have seen the compiler treat r11 like a "semi-volatile" register so I would use regs in this order as needed: r12, r10, r9, r8, r7.

I get the feeling that you believe "dcx2 must be wrong because I can do this and it doesn't crash."  The game might not crash, it just might act really weird.  Or it might mess up only on certain levels, or in boss fights, or when you change levels, or when you watch credits, etc.

You're rolling the dice and hoping that every single function in the stack is not depending on the value in r18 not changing.  Perhaps nothing depends on it.  Perhaps something does.  You have no way to know.  You could try looking at every stack frame in the current call stack, but that's just for that one specific call stack, and such a function can be called from many places, and its callers can have other callers who may or may not depend on r18, and it becomes almost impossible to verify that r18 is always safe no matter what you're doing in the game.

Deathwolf

#6
ok ok sorry for that. I'll use the stack frame. Of course I believe you!

BTW your code worked fine  :) Now I just want to make a "roller" code but it freez D:

stwu r1,-80(r1)
stmw r14,8(r1)

cmpwi r4,0x02
bne- END
li r4,0x0009
b Default

END:
cmpwi r4,0x00
bne- END2
li r4,0x000F
b Default

END2:
cmpwi r4,0x03
bne- END3
li r4,0x000B
b Default

END3:
cmpwi r4,0x01
bne- Default
li r4,0x0010

Default:
stw r4,4(r3)

lmw r14,8(r1)         
addi r1,r1,80       

uff it's r4. can we move this to r14?
lolz

dcx2

nonono, you don't need to create a stack frame.  Everything below r13, with special exceptions, does not require a stack frame.

Seriously, just use r12-r7 for this function.  You don't need a stack frame if you look at what registers are being used.

Rollers usually require some sort of button activator, otherwise your code will never stop rolling.

You should hook 807BC940:  1C04001C   mulli   r0,r4,28 instead.  The result in r0 is used to calculate the offset into some array of items that are 28 bytes each.  If you change r4 after, then the offset will not match and it could cause problems.

Deathwolf

Yeah I use the hook address of mulli and it works now.

cmpwi r4,0x02
bne- END
li r4,0x0009
b Default

END:
cmpwi r4,0x00
bne- END2
li r4,0x000F
b Default

END2:
cmpwi r4,0x03
bne- END3
li r4,0x000B
b Default

END3:
cmpwi r4,0x01
bne- Default
li r4,0x0010

Default:
mulli   r0,r4,28
lolz