~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/m32r/include/asm/flat.h

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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_argvp_envp_on_stack()              0
 
16
#define flat_old_ram_flag(flags)                (flags)
 
17
#define flat_set_persistent(relval, p)          0
 
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, persistent) \
 
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 */