xref: /haiku/src/system/libroot/os/arch/ppc/byteorder.S (revision 1d9d47fc72028bb71b5f232a877231e59cfe2438)
1/*
2** Copyright 2003, Axel D�fler, axeld@pinc-software.de. All rights reserved.
3** Distributed under the terms of the OpenBeOS License.
4*/
5
6#define FUNCTION(x) .global x; .type x,@function; x
7
8.text
9
10/* uint16 __swap_int16(uint16 value)
11 *                     r3
12 */
13FUNCTION(__swap_int16):
14		rlwinm	%r4, %r3, 8, 16, 23		// byte 4 -> byte 3 (clear other bits)
15		rlwimi	%r4, %r3, 24, 24, 31	// byte 3 -> byte 4 (copy into)
16		mr		%r3, %r4				// copy to result register
17		blr
18
19
20/* uint32 __swap_int32(uint32 value)
21 *                     r3
22 */
23FUNCTION(__swap_int32):
24		rlwinm	%r4, %r3, 24, 0, 31		// byte 4 to 1, byte 2 to 3
25		rlwimi	%r4, %r3, 8, 8, 15		// byte 3 to 2
26		rlwimi	%r4, %r3, 8, 24, 31		// byte 1 to 4
27		mr		%r3, %r4
28		blr
29
30
31/* uint64 __swap_int64(uint64 value)
32 *                     r3/r4
33 */
34FUNCTION(__swap_int64):
35		rlwinm	%r5, %r3, 24, 0, 31		// byte 4 to 5, byte 2 to 7
36		rlwimi	%r5, %r3, 8, 8, 15		// byte 3 to 6
37		rlwimi	%r5, %r3, 8, 24, 31		// byte 1 to 8
38		rlwinm	%r3, %r4, 24, 0, 31		// byte 8 to 1, byte 6 to 3
39		rlwimi	%r3, %r4, 8, 8, 15		// byte 7 to 2
40		rlwimi	%r3, %r4, 8, 24, 31		// byte 5 to 4
41		mr		%r4, %r5				// copy lower 32 bits
42		blr
43
44
45/* TODO: The following functions can surely be optimized. A simple optimization
46 * would be to define macros with the contents of the __swap_int{32,64}
47 * functions and use those instead of calling the functions.
48 */
49
50/* float __swap_float(float value)
51 *					  f1
52 */
53FUNCTION(__swap_float):
54		// push a stack frame
55		stwu	%r1, -32(%r1)
56		mflr	%r0
57		stw		%r0, 36(%r1)
58
59		// %f1 -> %r3
60		stfs	%f1, 20(%r1)
61		lwz		%r3, 20(%r1)
62
63		// let __swap_int32 convert %r3
64		bl		__swap_int32
65
66		// %r3 -> %f1
67		stw		%r3, 20(%r1)
68		lfs		%f1, 20(%r1)
69
70		// pop the stack frame
71		lwz		%r0, 36(%r1)
72		mtlr	%r0
73		addi	%r1, %r1, 32
74		blr
75
76/* double __swap_double(double value)
77 *						f1
78 */
79FUNCTION(__swap_double):
80		// push a stack frame
81		stwu	%r1, -32(%r1)
82		mflr	%r0
83		stw		%r0, 36(%r1)
84
85		// %f1 -> (%r3:%r4)
86		stfd	%f1, 20(%r1)
87		lwz		%r3, 20(%r1)
88		lwz		%r4, 24(%r1)
89
90		// let __swap_int64 convert %r3:%r4
91		bl		__swap_int64
92
93		// (%r3:%r4) -> %f1
94		stw		%r3, 20(%r1)
95		stw		%r4, 24(%r1)
96		lfd		%f1, 20(%r1)
97
98		// pop the stack frame
99		lwz		%r0, 36(%r1)
100		mtlr	%r0
101		addi	%r1, %r1, 32
102		blr
103