at v2.6.25 146 lines 4.5 kB view raw
1/* 2 * include/asm-m32r/flat.h 3 * 4 * uClinux flat-format executables 5 * 6 * Copyright (C) 2004 Kazuhiro Inaoka 7 * 8 * This file is subject to the terms and conditions of the GNU General Public 9 * License. See the file "COPYING" in the main directory of this archive for 10 * more details. 11 */ 12#ifndef __ASM_M32R_FLAT_H 13#define __ASM_M32R_FLAT_H 14 15#define flat_stack_align(sp) (*sp += (*sp & 3 ? (4 - (*sp & 3)): 0)) 16#define flat_argvp_envp_on_stack() 0 17#define flat_old_ram_flag(flags) (flags) 18#define flat_set_persistent(relval, p) 0 19#define flat_reloc_valid(reloc, size) \ 20 (((reloc) - textlen_for_m32r_lo16_data) <= (size)) 21#define flat_get_addr_from_rp(rp, relval, flags, persistent) \ 22 m32r_flat_get_addr_from_rp(rp, relval, (text_len) ) 23 24#define flat_put_addr_at_rp(rp, addr, relval) \ 25 m32r_flat_put_addr_at_rp(rp, addr, relval) 26 27/* Convert a relocation entry into an address. */ 28static inline unsigned long 29flat_get_relocate_addr (unsigned long relval) 30{ 31 return relval & 0x00ffffff; /* Mask out top 8-bits */ 32} 33 34#define flat_m32r_get_reloc_type(relval) ((relval) >> 24) 35 36#define M32R_SETH_OPCODE 0xd0c00000 /* SETH instruction code */ 37 38#define FLAT_M32R_32 0x00 /* 32bits reloc */ 39#define FLAT_M32R_24 0x01 /* unsigned 24bits reloc */ 40#define FLAT_M32R_16 0x02 /* 16bits reloc */ 41#define FLAT_M32R_LO16 0x03 /* signed low 16bits reloc (low()) */ 42#define FLAT_M32R_LO16_DATA 0x04 /* signed low 16bits reloc (low()) 43 for a symbol in .data section */ 44 /* High 16bits of an address used 45 when the lower 16bbits are treated 46 as unsigned. 47 To create SETH instruction only. 48 0x1X: X means a number of register. 49 0x10 - 0x3F are reserved. */ 50#define FLAT_M32R_HI16_ULO 0x10 /* reloc for SETH Rn,#high(imm16) */ 51 /* High 16bits of an address used 52 when the lower 16bbits are treated 53 as signed. 54 To create SETH instruction only. 55 0x2X: X means a number of register. 56 0x20 - 0x4F are reserved. */ 57#define FLAT_M32R_HI16_SLO 0x20 /* reloc for SETH Rn,#shigh(imm16) */ 58 59static unsigned long textlen_for_m32r_lo16_data = 0; 60 61static inline unsigned long m32r_flat_get_addr_from_rp (unsigned long *rp, 62 unsigned long relval, 63 unsigned long textlen) 64{ 65 unsigned int reloc = flat_m32r_get_reloc_type (relval); 66 textlen_for_m32r_lo16_data = 0; 67 if (reloc & 0xf0) { 68 unsigned long addr = htonl(*rp); 69 switch (reloc & 0xf0) 70 { 71 case FLAT_M32R_HI16_ULO: 72 case FLAT_M32R_HI16_SLO: 73 if (addr == 0) { 74 /* put "seth Rn,#0x0" instead of 0 (addr). */ 75 *rp = (M32R_SETH_OPCODE | ((reloc & 0x0f)<<24)); 76 } 77 return addr; 78 default: 79 break; 80 } 81 } else { 82 switch (reloc) 83 { 84 case FLAT_M32R_LO16: 85 return htonl(*rp) & 0xFFFF; 86 case FLAT_M32R_LO16_DATA: 87 /* FIXME: The return value will decrease by textlen 88 at m32r_flat_put_addr_at_rp () */ 89 textlen_for_m32r_lo16_data = textlen; 90 return (htonl(*rp) & 0xFFFF) + textlen; 91 case FLAT_M32R_16: 92 return htons(*(unsigned short *)rp) & 0xFFFF; 93 case FLAT_M32R_24: 94 return htonl(*rp) & 0xFFFFFF; 95 case FLAT_M32R_32: 96 return htonl(*rp); 97 default: 98 break; 99 } 100 } 101 return ~0; /* bogus value */ 102} 103 104static inline void m32r_flat_put_addr_at_rp (unsigned long *rp, 105 unsigned long addr, 106 unsigned long relval) 107{ 108 unsigned int reloc = flat_m32r_get_reloc_type (relval); 109 if (reloc & 0xf0) { 110 unsigned long Rn = reloc & 0x0f; /* get a number of register */ 111 Rn <<= 24; /* 0x0R000000 */ 112 reloc &= 0xf0; 113 switch (reloc) 114 { 115 case FLAT_M32R_HI16_ULO: /* To create SETH Rn,#high(imm16) */ 116 *rp = (M32R_SETH_OPCODE | Rn 117 | ((addr >> 16) & 0xFFFF)); 118 break; 119 case FLAT_M32R_HI16_SLO: /* To create SETH Rn,#shigh(imm16) */ 120 *rp = (M32R_SETH_OPCODE | Rn 121 | (((addr >> 16) + ((addr & 0x8000) ? 1 : 0)) 122 & 0xFFFF)); 123 break; 124 } 125 } else { 126 switch (reloc) { 127 case FLAT_M32R_LO16_DATA: 128 addr -= textlen_for_m32r_lo16_data; 129 textlen_for_m32r_lo16_data = 0; 130 case FLAT_M32R_LO16: 131 *rp = (htonl(*rp) & 0xFFFF0000) | (addr & 0xFFFF); 132 break; 133 case FLAT_M32R_16: 134 *(unsigned short *)rp = addr & 0xFFFF; 135 break; 136 case FLAT_M32R_24: 137 *rp = (htonl(*rp) & 0xFF000000) | (addr & 0xFFFFFF); 138 break; 139 case FLAT_M32R_32: 140 *rp = addr; 141 break; 142 } 143 } 144} 145 146#endif /* __ASM_M32R_FLAT_H */