1 // Copyright (c) 2015-2016 The Khronos Group Inc.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 #include "source/spirv_endian.h"
20 I32_ENDIAN_LITTLE
= 0x03020100ul
,
21 I32_ENDIAN_BIG
= 0x00010203ul
,
24 // This constant value allows the detection of the host machine's endianness.
25 // Accessing it through the "value" member is valid due to C++11 section 3.10
28 unsigned char bytes
[4];
30 } o32_host_order
= {{0, 1, 2, 3}};
32 #define I32_ENDIAN_HOST (o32_host_order.value)
34 uint32_t spvFixWord(const uint32_t word
, const spv_endianness_t endian
) {
35 if ((SPV_ENDIANNESS_LITTLE
== endian
&& I32_ENDIAN_HOST
== I32_ENDIAN_BIG
) ||
36 (SPV_ENDIANNESS_BIG
== endian
&& I32_ENDIAN_HOST
== I32_ENDIAN_LITTLE
)) {
37 return (word
& 0x000000ff) << 24 | (word
& 0x0000ff00) << 8 |
38 (word
& 0x00ff0000) >> 8 | (word
& 0xff000000) >> 24;
44 uint64_t spvFixDoubleWord(const uint32_t low
, const uint32_t high
,
45 const spv_endianness_t endian
) {
46 return (uint64_t(spvFixWord(high
, endian
)) << 32) | spvFixWord(low
, endian
);
49 spv_result_t
spvBinaryEndianness(spv_const_binary binary
,
50 spv_endianness_t
* pEndian
) {
51 if (!binary
->code
|| !binary
->wordCount
) return SPV_ERROR_INVALID_BINARY
;
52 if (!pEndian
) return SPV_ERROR_INVALID_POINTER
;
55 memcpy(bytes
, binary
->code
, sizeof(uint32_t));
57 if (0x03 == bytes
[0] && 0x02 == bytes
[1] && 0x23 == bytes
[2] &&
59 *pEndian
= SPV_ENDIANNESS_LITTLE
;
63 if (0x07 == bytes
[0] && 0x23 == bytes
[1] && 0x02 == bytes
[2] &&
65 *pEndian
= SPV_ENDIANNESS_BIG
;
69 return SPV_ERROR_INVALID_BINARY
;
72 bool spvIsHostEndian(spv_endianness_t endian
) {
73 return ((SPV_ENDIANNESS_LITTLE
== endian
) &&
74 (I32_ENDIAN_LITTLE
== I32_ENDIAN_HOST
)) ||
75 ((SPV_ENDIANNESS_BIG
== endian
) &&
76 (I32_ENDIAN_BIG
== I32_ENDIAN_HOST
));