English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 01 August 2021, 12:05   #1
mr.spiv
Registered User
 
mr.spiv's Avatar
 
Join Date: Aug 2006
Location: Finland
Age: 51
Posts: 242
I got fooled by address register word size operations

I had a bug that haunted me for quite some time.. me and my stupid premature optimizations. Anyway, typically address register word size operations sign extend and stuff automatically to 32 bits. I tend to use that routinely. So, my code had:
Code:
SUBA.W A2,A2
in an attempt to clear A2 but if bits 31-16 contained data they remained and did not get sign extended to all 0 or 1 as I had assumed. Took a while to figure this out from the depths of macro mush and admit being caught pants down I had to run few more experiments and code like:
Code:
MOVE.L #$00AA0001,A0
MOVE.L #$00110002,A1
SUBA.W A1,A0
Produces #$00A9FFFF and not #$FFFFFFFF as I had expected. What confuses me is that #$00AA0001 in A0 does not seem to get sign extended to #$00000001 but apparently #$00110002 in A1 does get sign extended to #$00000002. What I am not seeing/knowing/understanding here?
mr.spiv is offline  
Old 01 August 2021, 12:21   #2
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Is the source that is sign extended in Ax.w operations.

So this is like:
Code:
MOVE.L #$00AA0001,A0
MOVE.L #$00110002,A1
MOVE.W A1,A1
SUBA.L A1,A0
Yes, you could use MOVE.W Ax,Ax to sign extend Ax registers

This explain also the SUBA.W A2,A2
ross is offline  
Old 01 August 2021, 12:36   #3
mr.spiv
Registered User
 
mr.spiv's Avatar
 
Join Date: Aug 2006
Location: Finland
Age: 51
Posts: 242
Quote:
Originally Posted by ross View Post
Is the source that is sign extended in Ax.w operations.
Right.. I had to reread what the manual actually says and yes "Word-sized source operands are sign-extended to 32-bit quantities prior to the subtraction." Sigh, I have actually missed this detail all these years
mr.spiv is offline  
Old 02 August 2021, 07:50   #4
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,323
There is also the trick to use CMPA.W on same reg to check if a signed value fits in 16-bit (i.e. is between $ffff8000 and $00007fff).
meynaf is offline  
Old 02 August 2021, 19:54   #5
Photon
Moderator
 
Photon's Avatar
 
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
SUB and CMP should use the exact same logic, cmp is sub without store. From memory there is no time gain (or loss of time loss ) for An as there is for Dn (on 68000) because of the extra operations (also includes ADD). I.e. if you go by 6c instead of 8c check footnotes.

Code:
move.l #$0ffffffff,a0
sub.w a0,a0
move.l #$ffff0fff,a1
sub.w a1,a1

a0=$10000000
a1=$ffff0000
SUB and SUBA -> SUBA instruction, according to AsmOne debugger. Is there a way to get a separate, different SUB <ea>,An opcode?

Last edited by Photon; 02 August 2021 at 20:57.
Photon is offline  
Old 02 August 2021, 20:48   #6
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,039
Nope, that specific mode/reg combo of sub is used to encode subx.
a/b is offline  
Old 02 August 2021, 21:52   #7
Photon
Moderator
 
Photon's Avatar
 
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
Quote:
Originally Posted by a/b View Post
Nope, that specific mode/reg combo of sub is used to encode subx.
OK, I was thinking of MOVEA. No diff there either? And flags unaffected?

Also, ADDA/ADD ea,An (and same for move) doesn't sign-extend according to Motorola.

(I'm only following through and being exhaustive.) So, only SUB and CMP.

But where there's an unusual behavior there could be a niche case to abuse for those two.
Photon is offline  
Old 02 August 2021, 22:36   #8
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,039
No difference on opcode level, each movea variant is using a unique opcode (there is no opcode duplication with move). Basically, it's all move $2xxx/$3xxx but if destination is an areg, move is changed to movea (to indicate different behaviour regarding ccr etc.). Move $1xxx (.b) to areg are all invalid (exception).
a/b is offline  
Old 02 August 2021, 22:43   #9
mr.spiv
Registered User
 
mr.spiv's Avatar
 
Join Date: Aug 2006
Location: Finland
Age: 51
Posts: 242
Quote:
Originally Posted by meynaf View Post
There is also the trick to use CMPA.W on same reg to check if a signed value fits in 16-bit (i.e. is between $ffff8000 and $00007fff).
Ha, that was neat Never thought about that before. Maybe I find use for that some day.

Last edited by mr.spiv; 03 August 2021 at 08:09.
mr.spiv is offline  
Old 02 August 2021, 23:24   #10
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,411
This is certainly something I ran into as well. It's a good source for rather subtle bugs
roondar is offline  
Old 03 August 2021, 00:06   #11
Photon
Moderator
 
Photon's Avatar
 
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
Quote:
Originally Posted by a/b View Post
No difference on opcode level, each movea variant is using a unique opcode (there is no opcode duplication with move). Basically, it's all move $2xxx/$3xxx but if destination is an areg, move is changed to movea (to indicate different behaviour regarding ccr etc.). Move $1xxx (.b) to areg are all invalid (exception).
It's changed by what? Not the CPU, the Assembler. My comment was only regarding CPU legal, different opcodes that could have different or same behavior. For exploration (and exactness) since the question is already answered.
Photon is offline  
Old 03 August 2021, 10:05   #12
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,323
Quote:
Originally Posted by Photon View Post
OK, I was thinking of MOVEA. No diff there either? And flags unaffected?
No flags affected by MOVEA, ADDA, SUBA. Only CMPA does.


Quote:
Originally Posted by Photon View Post
Also, ADDA/ADD ea,An (and same for move) doesn't sign-extend according to Motorola.
Are you sure Motorola documented that ? MOVEA and ADDA sure also do a sign-extend.



Quote:
Originally Posted by a/b View Post
Move $1xxx (.b) to areg are all invalid (exception).
If you like odd things : even though everything byte related is invalid if address regs are used, 020+ MOVES instruction isn't.


Quote:
Originally Posted by Photon View Post
It's changed by what? Not the CPU, the Assembler. My comment was only regarding CPU legal, different opcodes that could have different or same behavior. For exploration (and exactness) since the question is already answered.
It's changed by the cpu as well, if you consider MOVEA as a different operation compared to usual MOVE.
Because contrary to ADDA,SUBA,CMPA which all have specific opcodes, MOVEA occupies natural space where MOVE (to An) would be.
meynaf is offline  
Old 03 August 2021, 10:31   #13
bebbo
bye
 
Join Date: Jun 2016
Location: Some / Where
Posts: 680
Quote:
Originally Posted by Photon View Post
SUB and CMP should use the exact same logic, cmp is sub without store. From memory there is no time gain (or loss of time loss ) for An as there is for Dn (on 68000) because of the extra operations (also includes ADD). I.e. if you go by 6c instead of 8c check footnotes.

Code:
move.l #$0ffffffff,a0
sub.w a0,a0
move.l #$ffff0fff,a1
sub.w a1,a1

a0=$10000000
a1=$ffff0000
SUB and SUBA -> SUBA instruction, according to AsmOne debugger. Is there a way to get a separate, different SUB <ea>,An opcode?

a0 = $00000000


the sub.w a0,a0 uses a0.w sign extended
$ffff -> $ffffffff
$ffffffff - $ffffffff = $00000000


the word used in adda/suba is sign extended before a long add/sub is calculated
bebbo is offline  
Old 03 August 2021, 13:38   #14
Photon
Moderator
 
Photon's Avatar
 
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
Quote:
Originally Posted by meynaf View Post
Are you sure Motorola documented that ? MOVEA and ADDA sure also do a sign-extend.
I'm sorry, it was mentioned a little later for both, in the opmode field. But testing it, here is something curious. MOVE sign extends, but ADD doesn't?
Code:
	move.l #$0000ffff,a0
	move.l #$0000ffff,a1
	add.w a0,a1			;a1=$0000fffe
	move.w a0,a2			;a2=$ffffffff
At least I've tried with different values and I can't make the upper word of a1 change at all.

Quote:
Originally Posted by meynaf View Post
It's changed by the cpu as well, if you consider MOVEA as a different operation compared to usual MOVE.
Because contrary to ADDA,SUBA,CMPA which all have specific opcodes, MOVEA occupies natural space where MOVE (to An) would be.
Maybe for the Debugger, but I mean changing the opcode from an imaginary existing move ea,An to movea ea,An. As in two different instructions in the CPU, one of them would then be in an unnatural space
Photon is offline  
Old 03 August 2021, 14:06   #15
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by Photon View Post
But testing it, here is something curious. MOVE sign extends, but ADD doesn't?
This is like:
Code:
	move.l #$0000ffff,a0
        move.w a0,a0
	move.l #$0000ffff,a1
	add.l a0,a1			;a1=$0000fffe
	move.w a0,a2			;a2=$ffffffff
Nothing strange here

The arithmetic operations are always full 32bit as far as the Ax registers are concerned.
ross is offline  
Old 03 August 2021, 14:28   #16
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,216
Quote:
Originally Posted by Photon View Post
I'm sorry, it was mentioned a little later for both, in the opmode field. But testing it, here is something curious. MOVE sign extends, but ADD doesn't?

Operations on Ax registers sign extend the source, not the destinatiion. That is, the left operand is extended, but not the target address register (that would not really make sense...).


For "movea" (not to be confused with "move" which does not take an address register as target), the left-hand operand is thus sign extended to 32 bit before performing the move. For "adda" (not to be confused with "add" which does not take an address register as target), the operand to be added is sign extended, but not the target to which it is added.


Likewise for suba (not "sub" which does not exist for address register targets).


That your assembler converts move to movea, sub to suba and add to adda is just a convenience function. The opcodes work differently. (sign extension just being one difference, setting flags being another).
Thomas Richter is offline  
Old 03 August 2021, 16:27   #17
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,323
Quote:
Originally Posted by Photon View Post
At least I've tried with different values and I can't make the upper word of a1 change at all.
Try this then :
Code:
 move.l #$00007fff,a0
 move.l #$0000ffff,a1
 add.w a0,a1			; a1=00017ffe
meynaf is offline  
Old 05 August 2021, 13:16   #18
Photon
Moderator
 
Photon's Avatar
 
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
Quote:
Originally Posted by meynaf View Post
Try this then :
Code:
 move.l #$00007fff,a0
 move.l #$0000ffff,a1
 add.w a0,a1			; a1=00017ffe
Hm. Well, source is unsigned so this doesn't really test it. But move.l #$ffff7fff,a0 gives the same result, so I'm convinced.

adda.w sign extends source and performs a full 32-bit add.
Photon is offline  
Old 05 August 2021, 14:00   #19
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,323
Quote:
Originally Posted by Photon View Post
Hm. Well, source is unsigned so this doesn't really test it. But move.l #$ffff7fff,a0 gives the same result, so I'm convinced.

adda.w sign extends source and performs a full 32-bit add.
If you want to see all effects at once :
Code:
 move.l #$55558888,a0
 move.l #$11111111,a1
 adda.w a0,a1           ; a1=$11109999
meynaf is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Address register indirect, word vs long deimos Coders. Asm / Hardware 4 15 November 2019 16:58
Logging Blitter Operations? mcgeezer support.WinUAE 2 02 June 2019 10:23
Address register expected Nightfox Coders. Asm / Hardware 4 12 August 2016 11:51
WinUAE Debugger - Address Register Watchpoints SparkyNZ Coders. Asm / Hardware 3 16 June 2015 22:39
Word vs not word aligned playfield question nandius_c Coders. Asm / Hardware 8 03 December 2013 12:03

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 06:25.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.09869 seconds with 15 queries