Commit 9d9aa41b authored by Ben Avison's avatar Ben Avison
Browse files

Miscellaneous v6-related updates

Detail:
 * Stopped calling the broken abort fixup code when running under VMSAv6.
   Might be desirable to update it, possibly farmed out to a separate module -
   still need to think about this.
 * Unaligned load optimisations can now be disabled by the global NoUnaligned
   flag for testing purposes.
 * Extended OS_ReadUnsigned to permit reading of 64-bit unsigned integers.
   See Docs.ReadUnsigned for more details. Also sped it up by using MLA
   (or UMLAL) for most digits rather than repeated addition.
 * Bugfix is OS_GSRead: an uninitialised r0 was being passed to
   OS_ReadUnsigned, causing undesirable effects on rare occasions.
Admin:
  Tested on a rev B7 beagleboard.

Version 5.35, 4.79.2.98.2.8. Tagged as 'Kernel-5_35-4_79_2_98_2_8'
parent 76cbfa84
OS_ReadUnsigned
(SWI &21)
On entry
R0 bits 0-7 = base in the range 2-36 (else 10 assumed)
bits 8-27 reserved, should be 0
bit 28 set => read a 64-bit value to r2,r3
bit 29 set => restrict range to 0 - R2 (or if bit 28 set, R2+(R3<<32))
bit 30 set => restrict range to 0- 255
bit 31 set => check terminator is a control character or space
R1 = pointer to string
R2 = least significant word of maximum value if R0 bit 29 set
R3 = most significant word of maximum value if R0 bits 28 and 29 both set
R4 = &45444957 ("WIDE") if this API applies, otherwise see PRM 1-448
On exit
R0 preserved
R1 = pointer to terminator character
R2 = least significant word of value
R3 = most significant word of value if R0 bit 28 set on entry
R4 = bitmask of R0 flags understood by current kernel (currently &F0000000)
Suggestions for future flag uses:
* permit "0x" (hexadecimal), "0" (octal) and "0b" or "%" (binary) prefixes
* signed numbers
* floating point numbers
* negative bases
......@@ -13,11 +13,11 @@
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.35"
Module_Version SETA 535
Module_MinorVersion SETS "4.79.2.98.2.7"
Module_Date SETS "10 May 2009"
Module_ApplicationDate SETS "10-May-09"
Module_MinorVersion SETS "4.79.2.98.2.8"
Module_Date SETS "17 May 2009"
Module_ApplicationDate SETS "17-May-09"
Module_ComponentName SETS "Kernel"
Module_ComponentPath SETS "castle/RiscOS/Sources/Kernel"
Module_FullVersion SETS "5.35 (4.79.2.98.2.7)"
Module_HelpVersion SETS "5.35 (10 May 2009) 4.79.2.98.2.7"
Module_FullVersion SETS "5.35 (4.79.2.98.2.8)"
Module_HelpVersion SETS "5.35 (17 May 2009) 4.79.2.98.2.8"
END
......@@ -5,19 +5,19 @@
*
*/
#define Module_MajorVersion_CMHG 5.35
#define Module_MinorVersion_CMHG 4.79.2.98.2.7
#define Module_Date_CMHG 10 May 2009
#define Module_MinorVersion_CMHG 4.79.2.98.2.8
#define Module_Date_CMHG 17 May 2009
#define Module_MajorVersion "5.35"
#define Module_Version 535
#define Module_MinorVersion "4.79.2.98.2.7"
#define Module_Date "10 May 2009"
#define Module_MinorVersion "4.79.2.98.2.8"
#define Module_Date "17 May 2009"
#define Module_ApplicationDate "10-May-09"
#define Module_ApplicationDate "17-May-09"
#define Module_ComponentName "Kernel"
#define Module_ComponentPath "castle/RiscOS/Sources/Kernel"
#define Module_FullVersion "5.35 (4.79.2.98.2.7)"
#define Module_HelpVersion "5.35 (10 May 2009) 4.79.2.98.2.7"
#define Module_FullVersion "5.35 (4.79.2.98.2.8)"
#define Module_HelpVersion "5.35 (17 May 2009) 4.79.2.98.2.8"
#define Module_LibraryVersionInfo "5:35"
......@@ -632,6 +632,7 @@ GSREAD_XPandGetNextByte
STRB R1, [R12, #-1] ; terminate it
SUB R1, R12, R11 ; pointer to name or number
Push "R0"
MOV R0, #10
SWI XOS_ReadUnsigned ; check for number
Pull "R0"
BVS GSREAD_AngledThingAintNumber ; silly - has to be name
......
......@@ -28,28 +28,45 @@
; 'Number too big' is given if the result overflowed a 32-bit word
; In r1 -> string
; r0 = base to read number in (0 means any based number allowed)
; r0 = bits 0-7: base to read number in (0 means any based number allowed)
; bit 31 set -> check term chars for ok-ness
; bit 30 set -> restrict range to 00..FF
; bit 29 set -> restrict range to 0..R2 (inclusive)
; (overrides bit 30)
; bit 28 set -> read 64-bit value to R2,R3 and
; if applicable, range is in R2,R3
; r4 != &45444957 ("WIDE") -> legacy mode: bits 8-28 are considered part of the base
; Out VC : r1 -> first unused char, r2 = number
; VS : r1 unchanged, r2 = 0, current error block set
; either way, R4 = mask of flag bits supported
ReadUnsigned_Routine Entry "r0-r1, r3-r4, r9"
ReadUnsigned_Routine Entry "r0-r1, r3-r6, r9"
WritePSRc SVC_mode, r9
LDR lr, =&45444957
CMP r4, lr
MOVEQ r4, #(2_1111 :SHL: 28)
MOVNE r4, #(2_111 :SHL: 29)
STREQ r4, [stack, #3*4]
AND r11, r0, r4 ; Remember the input flags
ANDEQ r12, r0, #255 ; r12 := base
BICNE r12, r0, r4
; first set range limit
MOV r9, r2 ; limit value
TST r0, #3 :SHL: 29
MOV r9, r2 ; limit value lo word
TST r11, #1 :SHL: 28
MOVEQ r6, #0 ; limit value hi word
MOVNE r6, r3
TST r11, #3 :SHL: 29
MOVEQ r9, #-1 ; used unsigned; allows anything
TSTNE r0, #1 :SHL: 30
MOVEQ r6, #-1
TST r11, #1 :SHL: 30
MOVNE r9, #&FF
MOVNE r6, #0
MOV r11, r0 ; Remember the input flags
BIC r12, r0, #(2_111 :SHL: 29) ; r12 := base
CMP r12, #2 ; If base nonsensical, default to 10
RSBGES r14, r12, #36 ; ie. try to match most generally
MOVLT r12, #10
......@@ -62,8 +79,11 @@ ReadUnsigned_Routine Entry "r0-r1, r3-r4, r9"
TEQ r0, #"&" ; '&' always forces hex read
BNE %FT20
MOV r4, #16
BL ReadNumberInBase
BVS %FT95
TST r11, #1 :SHL: 28
ADR lr, %FT09
BEQ ReadNumberInBase
BNE Read64BitNumberInBase
09 BVS %FT95
10 STR r1, [sp, #4] ; Update string^
TST r11, #(1 :SHL: 31) ; Was the termcheck flag set ?
......@@ -72,8 +92,11 @@ ReadUnsigned_Routine Entry "r0-r1, r3-r4, r9"
CMP r0, #" " ; CtrlChar + space all ok
BGT %FT85 ; For bad term errors
15 CMP r2, r9
BHI %FT80
15 CMP r9, r2
SBCS lr, r6, r5
BCC %FT80
TST r11, #1 :SHL: 28
STRNE r5, [stack, #4*2]
PullEnv
ExitSWIHandler ; VClear already in lr
......@@ -83,11 +106,10 @@ ReadUnsigned_Routine Entry "r0-r1, r3-r4, r9"
BL ReadNumberInBase
MOVVS r4, r12 ; If we failed to read a decimal number
BVS %FT30 ; then use the one supplied (r12). r1 ok
LDRB r0, [r1] ; Is it base_number ?
LDRB r0, [r1], #1 ; Is it base_number ?
CMP r0, #"_" ; If not based, use supplied base
MOVNE r1, r10 ; to read from given start of string (spaces !)
MOVNE r4, r12 ; restore supplied base!
ADDEQ r1, r1, #1 ; Skip the '_'
MOVEQ r4, r2 ; Use this as new base
; Reading number in base r4
......@@ -95,8 +117,11 @@ ReadUnsigned_Routine Entry "r0-r1, r3-r4, r9"
30 CMP r4, #2 ; Is base valid (2..36) ?
RSBGES r0, r4, #36 ; LT -> invalid
BLT %FT90
BL ReadNumberInBase ; Read rest of number
BVS %FT95
TST r11, #1 :SHL: 28
ADR lr, %FT39
BEQ ReadNumberInBase ; Read rest of number
BNE Read64BitNumberInBase
39 BVS %FT95
B %BT10
......@@ -127,8 +152,10 @@ ReadUnsigned_Routine Entry "r0-r1, r3-r4, r9"
95
STR r2, [stack] ; Go set the current error
PullEnv
MOV r2, #0 ; Defined to return 0 on error
TST r11, #1 :SHL: 28
STRNE r2, [stack, #4*2] ; return MSB=0 on error too, if 64-bit read reqd
PullEnv
B SLVK_SetV
MakeErrorBlock BadBase
......@@ -140,18 +167,23 @@ ReadUnsigned_Routine Entry "r0-r1, r3-r4, r9"
; In r1 -> string, r4 = base (valid)
; Out VC : Number read in r2, r1 updated. r3 = number of chars used
; Out VC : Number read in r2, r1 updated. r3 = number of chars used, r5 = 0
; VS : r1 preserved, r2 -> error block
ReadNumberInBase Entry "r0, r1, r12"
MOV r2, #0 ; Result
MOV r3, #0 ; Number of valid digits read
MOV r5, #0
10 BL GetCharForReadNumber
BNE %FT50 ; Finished ?
MOV r12, r4
TST r2, #&F8000000 ; If EQ, can't possibly overflow in any base up to 26
MLAEQ r2, r4, r2, r0
BEQ %BT10
MOV r12, r4
MOV r14, #0 ; Multiply by repeated addition. Base <> 0 !
20 ADDS r14, r14, r2
BCS %FT90 ; Now checks for overflow !
......@@ -192,6 +224,45 @@ ReadNumberInBase Entry "r0, r1, r12"
EXIT
MakeErrorBlock NumbTooBig
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; Read64BitNumberInBase
; =====================
; In r1 -> string, r4 = base (valid)
; Out VC : Number read in r2 (lo) and r5 (hi), r1 updated. r3 = number of chars used
; VS : r1 preserved, r2 -> error block, r5 corrupted
Read64BitNumberInBase ALTENTRY
MOV r2, #0 ; Result lo
MOV r3, #0 ; Number of valid digits read
MOV r5, #0 ; Result hi
10 BL GetCharForReadNumber
BNE %BT50 ; Finished ?
[ :LNOT: NoARMv4
TST r5, #&F8000000 ; If EQ, can't possibly overflow in any base up to 26
MULEQ r5, r4, r5 ; r0,r5 = new_digit + (old_msw * base)<<32
UMLALEQ r0, r5, r4, r2 ; r0,r5 += old_lsw * base
MOVEQ r2, r0
BEQ %BT10
]
; Multiply by repeated addition. Base <> 0 !
SUBS r12, r4, #1 ; Final iteration has r2,r5 as dest, so one fewer main iterations
MOV r14, #0 ; r0,r14 is accumulator, initialised to new_digit,0
20 ADDS r0, r0, r2
ADCS r14, r14, r5
BCS %BT90
SUBS r12, r12, #1
BNE %BT20
ADDS r2, r0, r2
ADCS r5, r14, r5
BCC %BT10
B %BT90 ; Checks for overflow here too!
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; GetCharForReadNumber
......
......@@ -102,7 +102,7 @@ DespatchWord
; Osword Zero : Input a line
OsWord00 ROUT
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
LDRB R0, [R1, #0] ; lo-byte of address
LDRB R2, [R1, #1] ; hi-byte of address
ORR R0, R0, R2, LSL #8 ; R0 := address
......@@ -138,7 +138,7 @@ OsWord02 ROUT
ADREQ R2, TimerAlpha
ADRNE R2, TimerBeta
Swap R1, R2, CS ; if writing then R2 is destination
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
MOV R3, #5
10
LDRB R4, [R2], #1
......@@ -169,7 +169,7 @@ OsWord04 ROUT
MOVCS R2, R1 ; if writing then R1 is source
ADRCS R1, IntervalTimer
ADRCC R2, IntervalTimer ; else R2 is source
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
MOV R0, #5
10
LDRB R3, [R2], #1
......@@ -196,7 +196,7 @@ OsWord07 ROUT
MyOsWord
05
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
; Block not word aligned, so push it on the stack
SUB R13, R13, #8 ; create stack frame of 8 bytes
......@@ -223,7 +223,7 @@ OsWord07 ROUT
OsWord09 ROUT
Push R1 ; save pointer
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
LDRB R2, [R1, #0] ; X lo-byte
LDRB R0, [R1, #1] ; X hi-byte
ORR R0, R2, R0, LSL #8
......@@ -501,7 +501,7 @@ OsWord0EGamma ROUT
OsWord0EDelta ROUT
LDR R1, RealTime +0
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
STRB R1, [R4, #0]
MOV R1, R1, LSR #8
STRB R1, [R4, #1]
......
......@@ -553,6 +553,11 @@ DAbPreVeneer ROUT
SUB r11, r2, #8*4 ; r11 -> register bank
STR r4, [sp, #7*4] ; store aborter's PC in user register bank
[ {TRUE}
; For now, don't attempt any fixup on ARMv6+, since we'll get it wrong
B %FT90
]
TST r0, #T32_bit ; were they in Thumb mode? if so, give up now
BNE %FT90
......
......@@ -1236,7 +1236,7 @@ DoReadPOSVPOSO
DoSetScreenStart ROUT
Push R14
LDRB R3, [R1, #0] ; R3 = bitmask
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
LDRB R0, [R1, #1]
LDRB R2, [R1, #2]
ORR R0, R0, R2, LSL #8
......
......@@ -224,7 +224,7 @@ Pal_Blocksize # 0
MACRO
LoadCoordPair $x, $y, $basereg, $offset
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
ASSERT $x < $y
[ ($offset) :AND: 3 = 2
ADD $x, $basereg, #($offset)-2
......
......@@ -116,7 +116,7 @@ SetPal EntryS
B %FT20
10
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
LDRB r3, [lr, #2] ; r3 = red
ORR r2, r2, r3, LSL #8 ; r2 = &0000RRSS
LDRB r3, [lr, #3] ; r3 = green
......@@ -194,7 +194,7 @@ DoReadPalette Entry
LDROSB r0, FlashState
CMP r0, #1 ; CS => 1st state, CC => 2nd state
MOVCC r2, r3 ; r2 = current state
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
MOV r1, #4
10
STRB r2, [r4, #1]! ; store 4 bytes of data in block, starting R1+1
......
......@@ -1587,7 +1587,7 @@ DoOsWord13 ROUT
RSB R0, R4, R0, LSL R2 ; R0 = (X << XEigFactor)-OrgX
RSB R1, R5, R1, LSL R3 ; R1 = (Y << YEigFactor)-OrgY
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
STRB R0, [R6], #1
MOV R0, R0, LSR #8
STRB R0, [R6], #1
......@@ -1603,7 +1603,7 @@ DoOsWord13 ROUT
ADD R0, WsPtr, #GCsX
LDMIA R0, {R0, R1} ; get current cursor
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
STRB R0, [R6], #1
MOV R0, R0, LSR #8
STRB R0, [R6], #1
......
......@@ -240,7 +240,7 @@ SetMouseRectangle ROUT
DoMouseBox ROUT
Push "R1-R6, R14"
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
LDRB R2, [R1, #1] ; R2 = left
LDRB R0, [R1, #2]
ORR R2, R2, R0, LSL #8
......@@ -440,7 +440,7 @@ SetMouseMult ROUT
;
GetCoordPair ROUT
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
LDRB R0, [R1, #1] ; get X coordinate
LDRB R2, [R1, #2]
ORR R0, R0, R2, LSL #8
......@@ -514,7 +514,7 @@ StoreCoordPair ROUT
LDR R0, [WsPtr, #OrgX] ; subtract off origin
SUB R2, R2, R0
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
STRB R2, [R1, #1] ; store lo-byte of X
MOV R2, R2, LSR #8
STRB R2, [R1, #2] ; store hi-byte of X
......@@ -526,7 +526,7 @@ StoreCoordPair ROUT
LDR R0, [WsPtr, #OrgY] ; subtract off origin
SUB R3, R3, R0
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
STRB R3, [R1, #3] ; store lo-byte of Y
MOV R3, R3, LSR #8
STRB R3, [R1, #4] ; store hi-byte of Y
......
......@@ -3178,7 +3178,7 @@ DoReadFont
ADDCC R0, R0, #(Ecf1-2*8)
LDMIA R0, {R2,R3}
[ NoARMv6
[ NoARMv6 :LOR: NoUnaligned
STRB R2, [R1, #1]
MOV R2, R2, LSR #8
STRB R2, [R1, #2]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment