home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-m32r / flat.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  4.3 KB  |  146 lines

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