mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120298 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			214 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			214 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===- Endian.h - Utilities for IO with endian specific data ----*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // This file declares generic functions to read and write endian specific data.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #ifndef LLVM_SUPPORT_ENDIAN_H
 | |
| #define LLVM_SUPPORT_ENDIAN_H
 | |
| 
 | |
| #include "llvm/Config/config.h"
 | |
| #include "llvm/Support/Host.h"
 | |
| #include "llvm/Support/SwapByteOrder.h"
 | |
| #include "llvm/Support/type_traits.h"
 | |
| 
 | |
| namespace llvm {
 | |
| namespace support {
 | |
| 
 | |
| enum endianness {big, little};
 | |
| enum alignment {unaligned, aligned};
 | |
| 
 | |
| namespace detail {
 | |
| 
 | |
| template<typename value_type, alignment align>
 | |
| struct alignment_access_helper;
 | |
| 
 | |
| template<typename value_type>
 | |
| struct alignment_access_helper<value_type, aligned>
 | |
| {
 | |
|   value_type val;
 | |
| };
 | |
| 
 | |
| // Provides unaligned loads and stores.
 | |
| #pragma pack(push)
 | |
| #pragma pack(1)
 | |
| template<typename value_type>
 | |
| struct alignment_access_helper<value_type, unaligned>
 | |
| {
 | |
|   value_type val;
 | |
| };
 | |
| #pragma pack(pop)
 | |
| 
 | |
| } // end namespace detail
 | |
| 
 | |
| namespace endian {
 | |
|   template<typename value_type, alignment align>
 | |
|   static value_type read_le(const void *memory) {
 | |
|     value_type t =
 | |
|       reinterpret_cast<const detail::alignment_access_helper
 | |
|         <value_type, align> *>(memory)->val;
 | |
|     if (sys::isBigEndianHost())
 | |
|       return sys::SwapByteOrder(t);
 | |
|     return t;
 | |
|   }
 | |
| 
 | |
|   template<typename value_type, alignment align>
 | |
|   static void write_le(void *memory, value_type value) {
 | |
|     if (sys::isBigEndianHost())
 | |
|       value = sys::SwapByteOrder(value);
 | |
|     reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
 | |
|       (memory)->val = value;
 | |
|   }
 | |
| 
 | |
|   template<typename value_type, alignment align>
 | |
|   static value_type read_be(const void *memory) {
 | |
|     value_type t =
 | |
|       reinterpret_cast<const detail::alignment_access_helper
 | |
|         <value_type, align> *>(memory)->val;
 | |
|     if (sys::isLittleEndianHost())
 | |
|       return sys::SwapByteOrder(t);
 | |
|     return t;
 | |
|   }
 | |
| 
 | |
|   template<typename value_type, alignment align>
 | |
|   static void write_be(void *memory, value_type value) {
 | |
|     if (sys::isLittleEndianHost())
 | |
|       value = sys::SwapByteOrder(value);
 | |
|     reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
 | |
|       (memory)->val = value;
 | |
|   }
 | |
| }
 | |
| 
 | |
| namespace detail {
 | |
| 
 | |
| template<typename value_type,
 | |
|          endianness endian,
 | |
|          alignment  align>
 | |
| class packed_endian_specific_integral;
 | |
| 
 | |
| template<typename value_type>
 | |
| class packed_endian_specific_integral<value_type, little, unaligned> {
 | |
| public:
 | |
|   operator value_type() const {
 | |
|     return endian::read_le<value_type, unaligned>(Value);
 | |
|   }
 | |
| private:
 | |
|   uint8_t Value[sizeof(value_type)];
 | |
| };
 | |
| 
 | |
| template<typename value_type>
 | |
| class packed_endian_specific_integral<value_type, big, unaligned> {
 | |
| public:
 | |
|   operator value_type() const {
 | |
|     return endian::read_be<value_type, unaligned>(Value);
 | |
|   }
 | |
| private:
 | |
|   uint8_t Value[sizeof(value_type)];
 | |
| };
 | |
| 
 | |
| template<typename value_type>
 | |
| class packed_endian_specific_integral<value_type, little, aligned> {
 | |
| public:
 | |
|   operator value_type() const {
 | |
|     return endian::read_le<value_type, aligned>(&Value);
 | |
|   }
 | |
| private:
 | |
|   value_type Value;
 | |
| };
 | |
| 
 | |
| template<typename value_type>
 | |
| class packed_endian_specific_integral<value_type, big, aligned> {
 | |
| public:
 | |
|   operator value_type() const {
 | |
|     return endian::read_be<value_type, aligned>(&Value);
 | |
|   }
 | |
| private:
 | |
|   value_type Value;
 | |
| };
 | |
| 
 | |
| } // end namespace detail
 | |
| 
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                   <uint8_t, little, unaligned>  ulittle8_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                   <uint16_t, little, unaligned> ulittle16_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                   <uint32_t, little, unaligned> ulittle32_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                   <uint64_t, little, unaligned> ulittle64_t;
 | |
| 
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                    <int8_t, little, unaligned>  little8_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                    <int16_t, little, unaligned> little16_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                    <int32_t, little, unaligned> little32_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                    <int64_t, little, unaligned> little64_t;
 | |
| 
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                     <uint8_t, little, aligned>  aligned_ulittle8_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                     <uint16_t, little, aligned> aligned_ulittle16_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                     <uint32_t, little, aligned> aligned_ulittle32_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                     <uint64_t, little, aligned> aligned_ulittle64_t;
 | |
| 
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                      <int8_t, little, aligned>  aligned_little8_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                      <int16_t, little, aligned> aligned_little16_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                      <int32_t, little, aligned> aligned_little32_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                      <int64_t, little, aligned> aligned_little64_t;
 | |
| 
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                   <uint8_t, big, unaligned>     ubig8_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                   <uint16_t, big, unaligned>    ubig16_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                   <uint32_t, big, unaligned>    ubig32_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                   <uint64_t, big, unaligned>    ubig64_t;
 | |
| 
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                    <int8_t, big, unaligned>     big8_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                    <int16_t, big, unaligned>    big16_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                    <int32_t, big, unaligned>    big32_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                    <int64_t, big, unaligned>    big64_t;
 | |
| 
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                     <uint8_t, big, aligned>     aligned_ubig8_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                     <uint16_t, big, aligned>    aligned_ubig16_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                     <uint32_t, big, aligned>    aligned_ubig32_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                     <uint64_t, big, aligned>    aligned_ubig64_t;
 | |
| 
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                      <int8_t, big, aligned>     aligned_big8_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                      <int16_t, big, aligned>    aligned_big16_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                      <int32_t, big, aligned>    aligned_big32_t;
 | |
| typedef detail::packed_endian_specific_integral
 | |
|                      <int64_t, big, aligned>    aligned_big64_t;
 | |
| 
 | |
| } // end namespace llvm
 | |
| } // end namespace support
 | |
| 
 | |
| #endif
 |