6 #define TMP_ADDR 0x0001
10 #define LOC_SYM 0x0800
11 #define LOC_LOCAL 0x1000
12 #define LOC_MASK 0xff00
24 #define OP_XR(op) (op | 03)
25 #define OP_B(op) (op & ~01)
41 #define MIN(a, b) ((a) < (b) ? (a) : (b))
43 #define TMP_BT(t) ((t)->flags & TMP_ADDR ? LONGSZ : (t)->bt)
44 #define TMP_REG(t) ((t)->flags & LOC_REG ? (t)->addr : reg_get(~0))
45 #define TMP_REG2(t, r) ((t)->flags & LOC_REG && (t)->addr != r ? \
46 (t)->addr : reg_get(~(1 << r)))
47 #define TMPBT(bt) (BT_SZ(bt) >= 4 ? (bt) : (bt) & BT_SIGNED | 4)
49 #define R_BYTEREGS (1 << R_EAX | 1 << R_EDX | 1 << R_ECX)
50 #define TMP_BYTEREG(t) ((t)->flags & LOC_REG && \
51 (1 << (t)->addr) & R_BYTEREGS ? \
52 (t)->addr : reg_get(R_BYTEREGS))
54 static char buf
[SECSIZE
];
58 static long spsub_addr
;
61 #define TMP(i) (&tmps[ntmp - 1 - (i)])
65 long off
; /* offset from a symbol or a local */
73 static struct tmp
*regs
[NREGS
];
74 static int tmpregs
[] = {R_EAX
, R_ESI
, R_EDI
, R_EBX
, R_EDX
, R_ECX
};
76 #define MAXRET (1 << 8)
78 static long ret
[MAXRET
];
84 static void putint(char *s
, long n
, int l
)
92 static void os(char *s
, int n
)
100 static void oi(long n
, int l
)
110 static long codeaddr(void)
115 #define OP2(o2, o1) (0x010000 | ((o2) << 8) | (o1))
116 #define O2(op) (((op) >> 8) & 0xff)
117 #define O1(op) ((op) & 0xff)
118 #define MODRM(m, r1, r2) ((m) << 6 | (r1) << 3 | (r2))
120 static void op_x(int op
, int r1
, int r2
, int bt
)
127 oi(sz
== 1 ? O1(op
) & ~0x1 : O1(op
), 1);
132 /* op_*(): r=reg, m=mem, i=imm, s=sym */
133 static void op_rm(int op
, int src
, int base
, int off
, int bt
)
135 int dis
= off
== (char) off
? 1 : 4;
136 int mod
= dis
== 4 ? 2 : 1;
137 if (!off
&& base
!= R_EBP
)
139 op_x(op
, src
, base
, bt
);
140 oi(MODRM(mod
, src
& 0x07, base
& 0x07), 1);
147 static void op_rr(int op
, int src
, int dst
, int bt
)
149 op_x(op
, src
, dst
, bt
);
150 oi(MODRM(3, src
& 0x07, dst
& 0x07), 1);
153 static void op_rs(int op
, int src
, long addr
, int off
, int bt
)
155 op_x(op
, src
, 0, bt
);
156 oi(MODRM(0, src
& 0x07, 5), 1);
158 out_rela(addr
, codeaddr(), 0);
162 static void op_ri(int op
, int o3
, int src
, long num
, int bt
)
164 op_x(op
, src
, 0, bt
);
165 oi(MODRM(3, o3
, src
& 0x07), 1);
166 oi(num
, MIN(4, BT_SZ(bt
)));
169 static void op_sr(int op
, int src
, long addr
, int off
, int bt
)
171 op_x(op
, src
, 0, bt
);
172 oi(MODRM(0, src
& 0x07, 5), 1);
174 out_rela(addr
, codeaddr(), 1);
178 static void op_si(int op
, int o3
, long addr
, int off
, long num
, int bt
)
180 int sz
= MIN(4, BT_SZ(bt
));
182 oi(MODRM(0, o3
, 5), 1);
184 out_rela(addr
, codeaddr(), 1);
189 static void op_mi(int op
, int o3
, int base
, int off
, long num
, int bt
)
191 int dis
= off
== (char) off
? 1 : 4;
192 int mod
= dis
== 4 ? 2 : 1;
193 if (!off
&& base
!= R_EBP
)
195 op_x(op
, 0, base
, bt
);
196 oi(MODRM(mod
, 0, base
), 1);
199 oi(num
, MIN(4, BT_SZ(bt
)));
202 static long sp_push(int size
)
210 #define LOC_NEW(f, l) (((f) & ~LOC_MASK) | (l))
212 static void tmp_mem(struct tmp
*tmp
)
215 if (!(tmp
->flags
& LOC_REG
))
219 tmp
->addr
= -sp_push(LONGSZ
);
220 op_rm(I_MOV
, src
, R_EBP
, tmp
->addr
, TMPBT(TMP_BT(tmp
)));
222 tmp
->flags
= LOC_NEW(tmp
->flags
, LOC_MEM
);
225 static int movxx_x2r(int bt
)
229 o2
= bt
& BT_SIGNED
? 0xbe : 0xb6;
231 o2
= bt
& BT_SIGNED
? 0xbf : 0xb7;
232 return OP2(0x0f, o2
);
237 static void mov_r2r(int r1
, int r2
, unsigned bt1
, unsigned bt2
)
239 int s1
= bt1
& BT_SIGNED
;
240 int s2
= bt2
& BT_SIGNED
;
241 int sz1
= BT_SZ(bt1
);
242 int sz2
= BT_SZ(bt2
);
243 if (sz2
< 4 && (sz1
> sz2
|| s1
!= s2
)) {
244 op_rr(movxx_x2r(bt2
), r1
, r2
, 4);
247 if (sz1
== 4 && sz2
== 8 && s1
) {
248 op_rr(MOVSXD
, r2
, r1
, sz2
);
251 if (r1
!= r2
|| sz1
> sz2
)
252 op_rr(I_MOV
, r1
, r2
, TMPBT(bt2
));
255 static void mov_m2r(int dst
, int base
, int off
, int bt1
, int bt2
)
257 if (BT_SZ(bt1
) < 4) {
258 op_rm(movxx_x2r(bt1
), dst
, base
, off
,
259 bt1
& BT_SIGNED
&& BT_SZ(bt2
) == 8 ? 8 : 4);
260 mov_r2r(dst
, dst
, bt1
, bt2
);
262 op_rm(I_MOVR
, dst
, base
, off
, bt1
);
263 mov_r2r(dst
, dst
, bt1
, bt2
);
267 static void num_cast(struct tmp
*t
, unsigned bt
)
269 if (!(bt
& BT_SIGNED
) && BT_SZ(bt
) != LONGSZ
)
270 t
->addr
&= ((1l << (long) (BT_SZ(bt
) * 8)) - 1);
271 if (bt
& BT_SIGNED
&& BT_SZ(bt
) != LONGSZ
&&
272 t
->addr
> (1l << (BT_SZ(bt
) * 8 - 1)))
273 t
->addr
= -((1l << (BT_SZ(bt
) * 8)) - t
->addr
);
277 static void num_reg(int reg
, unsigned bt
, long num
)
279 int op
= I_MOVIR
+ (reg
& 7);
280 op_x(op
, 0, reg
, bt
);
284 static void tmp_reg(struct tmp
*tmp
, int dst
, unsigned bt
, int deref
)
286 if (deref
&& tmp
->flags
& TMP_ADDR
)
287 tmp
->flags
&= ~TMP_ADDR
;
290 if (tmp
->flags
& LOC_NUM
) {
293 num_reg(dst
, tmp
->bt
, tmp
->addr
);
296 tmp
->flags
= LOC_NEW(tmp
->flags
, LOC_REG
);
298 if (tmp
->flags
& LOC_SYM
) {
299 op_rr(I_MOVI
, 0, dst
, 4);
301 out_rela(tmp
->addr
, codeaddr(), 0);
305 tmp
->flags
= LOC_NEW(tmp
->flags
, LOC_REG
);
307 if (tmp
->flags
& LOC_REG
) {
309 mov_m2r(dst
, tmp
->addr
, 0, tmp
->bt
, bt
);
311 mov_r2r(tmp
->addr
, dst
, TMP_BT(tmp
),
312 tmp
->flags
& TMP_ADDR
? LONGSZ
: bt
);
313 regs
[tmp
->addr
] = NULL
;
315 if (tmp
->flags
& LOC_LOCAL
) {
317 mov_m2r(dst
, R_EBP
, tmp
->addr
+ tmp
->off
, tmp
->bt
, bt
);
319 op_rm(I_LEA
, dst
, R_EBP
, tmp
->addr
+ tmp
->off
, LONGSZ
);
321 if (tmp
->flags
& LOC_MEM
) {
322 int nbt
= deref
? LONGSZ
: TMP_BT(tmp
);
323 mov_m2r(dst
, R_EBP
, tmp
->addr
, nbt
, nbt
);
325 mov_m2r(dst
, dst
, 0, tmp
->bt
, bt
);
328 tmp
->bt
= tmp
->flags
& TMP_ADDR
? bt
: TMPBT(bt
);
330 tmp
->flags
= LOC_NEW(tmp
->flags
, LOC_REG
);
333 static void reg_free(int reg
)
338 for (i
= 0; i
< ARRAY_SIZE(tmpregs
); i
++)
339 if (!regs
[tmpregs
[i
]]) {
340 tmp_reg(regs
[reg
], tmpregs
[i
], regs
[reg
]->bt
, 0);
346 static void reg_for(int reg
, struct tmp
*t
)
348 if (regs
[reg
] && regs
[reg
] != t
)
352 static void tmp_mv(struct tmp
*t
, int reg
)
355 tmp_reg(t
, reg
, t
->bt
, 0);
358 static void tmp_to(struct tmp
*t
, int reg
, int bt
)
361 tmp_reg(t
, reg
, bt
? bt
: t
->bt
, 1);
364 static void tmp_drop(int n
)
367 for (i
= ntmp
- n
; i
< ntmp
; i
++)
368 if (tmps
[i
].flags
& LOC_REG
)
369 regs
[tmps
[i
].addr
] = NULL
;
374 static int tmp_pop(int reg
, int bt
)
376 struct tmp
*t
= TMP(0);
382 static struct tmp
*tmp_new(void)
385 return &tmps
[ntmp
++];
388 static void tmp_push(int reg
, unsigned bt
)
390 struct tmp
*t
= tmp_new();
397 void o_local(long addr
, unsigned bt
)
399 struct tmp
*t
= tmp_new();
402 t
->flags
= LOC_LOCAL
| TMP_ADDR
;
406 void o_num(long num
, unsigned bt
)
408 struct tmp
*t
= tmp_new();
414 void o_symaddr(long addr
, unsigned bt
)
416 struct tmp
*t
= tmp_new();
419 t
->flags
= LOC_SYM
| TMP_ADDR
;
423 void o_tmpdrop(int n
)
425 if (n
== -1 || n
> ntmp
)
435 #define FORK_REG R_EAX
437 /* make sure tmps remain intact after a conditional expression */
441 for (i
= 0; i
< ntmp
- 1; i
++)
445 void o_forkpush(void)
450 void o_forkjoin(void)
452 tmp_push(FORK_REG
, 0);
457 struct tmp
*t1
= TMP(0);
458 struct tmp
*t2
= TMP(1);
460 memcpy(&t
, t1
, sizeof(t
));
461 memcpy(t1
, t2
, sizeof(t
));
462 memcpy(t2
, &t
, sizeof(t
));
463 if (t1
->flags
& LOC_REG
)
465 if (t2
->flags
& LOC_REG
)
469 static int reg_get(int mask
)
472 for (i
= 0; i
< ARRAY_SIZE(tmpregs
); i
++)
473 if ((1 << tmpregs
[i
]) & mask
&& !regs
[tmpregs
[i
]])
475 for (i
= 0; i
< ARRAY_SIZE(tmpregs
); i
++)
476 if ((1 << tmpregs
[i
]) & mask
) {
477 reg_free(tmpregs
[i
]);
483 void tmp_copy(struct tmp
*t1
)
485 struct tmp
*t2
= tmp_new();
486 memcpy(t2
, t1
, sizeof(*t1
));
487 if (!(t1
->flags
& (LOC_REG
| LOC_MEM
)))
489 if (t1
->flags
& LOC_MEM
) {
490 tmp_reg(t2
, reg_get(~0), t2
->bt
, 0);
491 } else if (t1
->flags
& LOC_REG
) {
492 t2
->addr
= reg_get(~(1 << t1
->addr
));
493 op_rr(I_MOV
, t1
->addr
, t2
->addr
, TMPBT(TMP_BT(t1
)));
503 void o_cast(unsigned bt
)
505 struct tmp
*t
= TMP(0);
509 if (t
->flags
& LOC_NUM
) {
513 reg
= BT_SZ(bt
) > 1 ? TMP_REG(t
) : TMP_BYTEREG(t
);
517 long o_func_beg(char *name
, int global
)
519 long addr
= out_func_beg(name
, global
);
521 os("\x55", 1); /* push %rbp */
522 os("\x89\xe5", 2); /* mov %rsp, %rbp */
523 os("\x53\x56\x57", 3); /* push ebx; push esi; push edi */
530 memset(regs
, 0, sizeof(regs
));
531 os("\x81\xec", 2); /* sub $xxx, %rsp */
532 spsub_addr
= codeaddr();
537 void o_deref(unsigned bt
)
539 struct tmp
*t
= TMP(0);
540 if (t
->flags
& TMP_ADDR
)
541 tmp_to(t
, TMP_REG(t
), t
->bt
);
543 t
->flags
|= TMP_ADDR
;
548 struct tmp
*t
= TMP(0);
549 tmp_to(t
, TMP_REG(t
), t
->bt
);
552 static unsigned bt_op(unsigned bt1
, unsigned bt2
)
554 unsigned s1
= BT_SZ(bt1
);
555 unsigned s2
= BT_SZ(bt2
);
556 unsigned bt
= (bt1
| bt2
) & BT_SIGNED
| (s1
> s2
? s1
: s2
);
560 #define TMP_NUM(t) ((t)->flags & LOC_NUM && !((t)->flags & TMP_ADDR))
561 #define LOCAL_PTR(t) ((t)->flags & LOC_LOCAL && !((t)->flags & TMP_ADDR))
562 #define SYM_PTR(t) ((t)->flags & LOC_SYM && !((t)->flags & TMP_ADDR))
564 int o_popnum(long *c
)
566 struct tmp
*t
= TMP(0);
574 static void shx(int uop
, int sop
)
576 struct tmp
*t1
= TMP(0);
577 struct tmp
*t2
= TMP(1);
580 tmp_to(t1
, R_ECX
, 0);
581 r2
= TMP_REG2(t2
, R_ECX
);
584 op_rr(I_SHX
, bt
& BT_SIGNED
? sop
: uop
, r2
, TMPBT(bt
));
589 static int mulop(int uop
, int sop
, int reg
)
591 struct tmp
*t1
= TMP(0);
592 struct tmp
*t2
= TMP(1);
593 /* for div and mod, the sign of the second operand don't matter */
594 int bt
= uop
== 4 ? bt_op(t1
->bt
, t2
->bt
) : TMPBT(t2
->bt
);
595 if (t1
->flags
& LOC_REG
&& t1
->addr
!= R_EAX
&& t1
->addr
!= R_EDX
)
598 tmp_to(t2
, R_EAX
, bt
);
602 op_x(CQO_REG
, R_EAX
, R_EDX
, bt
);
604 op_rr(I_XOR
, R_EDX
, R_EDX
, bt
);
607 op_rr(I_MUL
, bt
& BT_SIGNED
? sop
: uop
, reg
, TMPBT(t2
->bt
));
613 tmps
[ntmp
- 1].flags
&= ~TMP_ADDR
;
614 tmps
[ntmp
- 1].bt
= LONGSZ
;
617 void o_ret(unsigned bt
)
622 os("\x31\xc0", 2); /* xor %eax, %eax */
623 ret
[nret
++] = o_jmp(0);
626 static void inc(int op
)
628 struct tmp
*t
= TMP(0);
631 if (t
->flags
& LOC_LOCAL
) {
633 off
= t
->addr
+ t
->off
;
639 op_rm(I_INC
, op
, reg
, off
, t
->bt
);
644 if (cmp_last
== codeaddr()) {
645 buf
[cmp_setl
+ 1] ^= 0x01;
647 o_num(0, 4 | BT_SIGNED
);
654 struct tmp
*t
= TMP(0);
656 unsigned bt
= TMPBT(t
->bt
);
659 op_rr(I_NOT
, id
, reg
, bt
);
662 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
664 void o_func_end(void)
667 for (i
= 0; i
< nret
; i
++)
669 os("\x5f\x5e\x5b", 3); /* pop edi; pop esi; pop ebx */
670 os("\xc9\xc3", 2); /* leave; ret; */
671 putint(buf
+ spsub_addr
, ALIGN(maxsp
- 3 * LONGSZ
, LONGSZ
), 4);
672 out_func_end(buf
, cur
- buf
);
675 long o_mklocal(int size
)
677 return sp_push(ALIGN(size
, LONGSZ
));
680 void o_rmlocal(long addr
, int sz
)
685 long o_arg(int i
, unsigned bt
)
687 return -LONGSZ
* (i
+ 2);
690 void o_assign(unsigned bt
)
692 struct tmp
*t1
= TMP(0);
693 struct tmp
*t2
= TMP(1);
694 int r1
= BT_SZ(bt
) > 1 ? TMP_REG(t1
) : TMP_BYTEREG(t1
);
697 tmp_to(t1
, r1
, TMPBT(bt
));
698 if (t2
->flags
& LOC_LOCAL
) {
700 off
= t2
->addr
+ t2
->off
;
702 reg
= TMP_REG2(t2
, r1
);
707 op_rm(I_MOV
, r1
, reg
, off
, bt
);
711 static long cu(int op
, long i
)
723 static int c_uop(int op
)
725 struct tmp
*t1
= TMP(0);
729 o_num(cu(op
, t1
->addr
), t1
->bt
);
733 static long cb(int op
, long a
, long b
, int *bt
, int bt1
, int bt2
)
735 *bt
= bt_op(bt1
, bt2
);
761 return (unsigned long) a
>> b
;
783 static int c_bop(int op
)
785 struct tmp
*t1
= TMP(0);
786 struct tmp
*t2
= TMP(1);
787 int locals
= LOCAL_PTR(t1
) + LOCAL_PTR(t2
);
788 int syms
= SYM_PTR(t1
) + SYM_PTR(t2
);
789 int nums
= TMP_NUM(t1
) + TMP_NUM(t2
);
791 if (syms
+ locals
== 2 || syms
+ nums
+ locals
!= 2)
794 if (op
!= O_ADD
&& op
!= O_SUB
|| op
== O_SUB
&& TMP_NUM(t2
))
796 bt
= BT_SIGNED
| LONGSZ
;
798 bt
= bt_op(t1
->bt
, t2
->bt
);
800 long o1
= TMP_NUM(t1
) ? t1
->addr
: t1
->off
;
801 long o2
= TMP_NUM(t2
) ? t2
->addr
: t2
->off
;
802 long ret
= cb(op
, o2
, o1
, &bt
, t2
->bt
, t1
->bt
);
808 long ret
= cb(op
, t2
->addr
, t1
->addr
, &bt
, t2
->bt
, t1
->bt
);
822 o_neg(op
== O_NEG
? 3 : 2);
834 static int binop(int op
, int *reg
)
836 struct tmp
*t1
= TMP(0);
837 struct tmp
*t2
= TMP(1);
839 unsigned bt
= bt_op(t1
->bt
, t2
->bt
);
842 r2
= TMP_REG2(t2
, r1
);
845 op_rr(op
, r2
, r1
, bt
);
850 static void bin_add(int op
)
852 /* opcode for O_ADD, O_SUB, O_AND, O_OR, O_XOR */
853 static int rx
[] = {0003, 0053, 0043, 0013, 0063};
855 int bt
= binop(rx
[op
& 0x0f], ®
);
859 static void bin_shx(int op
)
861 if ((op
& 0xff) == O_SHL
)
867 static void bin_mul(int op
)
869 if ((op
& 0xff) == O_MUL
)
870 tmp_push(R_EAX
, mulop(4, 5, R_EDX
));
871 if ((op
& 0xff) == O_DIV
)
872 tmp_push(R_EAX
, mulop(6, 7, R_ECX
));
873 if ((op
& 0xff) == O_MOD
)
874 tmp_push(R_EDX
, mulop(6, 7, R_ECX
));
877 static void o_cmp(int uop
, int sop
)
879 struct tmp
*t1
= TMP(0);
880 struct tmp
*t2
= TMP(1);
881 char set
[] = "\x0f\x00\xc0";
884 if (regs
[R_EAX
] && regs
[R_EAX
] != t1
&& regs
[R_EAX
] != t2
)
886 bt
= binop(I_CMP
, ®
);
887 set
[1] = bt
& BT_SIGNED
? sop
: uop
;
888 cmp_setl
= codeaddr();
889 os(set
, 3); /* setl %al */
890 os("\x0f\xb6\xc0", 3); /* movzbl %al, %eax */
891 tmp_push(R_EAX
, 4 | BT_SIGNED
);
892 cmp_last
= codeaddr();
895 static void bin_cmp(int op
)
919 static void o_bopset(int op
)
924 o_assign(TMP(1)->bt
);
929 if (!(op
& O_SET
) && !c_bop(op
))
935 if ((op
& 0xf0) == 0x00)
937 if ((op
& 0xf0) == 0x10)
939 if ((op
& 0xf0) == 0x20)
941 if ((op
& 0xf0) == 0x30)
945 void o_memcpy(int sz
)
947 struct tmp
*t0
= TMP(-1);
948 struct tmp
*t1
= TMP(0);
949 struct tmp
*t2
= TMP(1);
951 tmp_to(t0
, R_ECX
, 0);
954 os("\xf3\xa4", 2); /* rep movs */
958 void o_memset(int x
, int sz
)
960 struct tmp
*t0
= TMP(-2);
961 struct tmp
*t1
= TMP(-1);
962 struct tmp
*t2
= TMP(0);
965 tmp_to(t0
, R_EAX
, 0);
966 tmp_to(t1
, R_ECX
, 0);
968 os("\xf3\xaa", 2); /* rep stosb */
977 static long jx(int x
, long addr
)
981 os(op
, 2); /* jx $addr */
982 oi(addr
- codeaddr() - 4, 4);
983 return codeaddr() - 4;
986 static long jxtest(int x
, long addr
)
988 int bt
= tmp_pop(R_EAX
, 0);
989 op_rr(I_TEST
, R_EAX
, R_EAX
, bt
);
993 static long jxcmp(long addr
, int inv
)
996 if (codeaddr() != cmp_last
)
999 cur
= buf
+ cmp_setl
;
1000 x
= (unsigned char) buf
[cmp_setl
+ 1];
1001 return jx((inv
? x
: x
^ 0x01) & ~0x10, addr
);
1004 long o_jz(long addr
)
1006 long ret
= jxcmp(addr
, 0);
1007 return ret
!= -1 ? ret
: jxtest(0x84, addr
);
1010 long o_jnz(long addr
)
1012 long ret
= jxcmp(addr
, 1);
1013 return ret
!= -1 ? ret
: jxtest(0x85, addr
);
1016 long o_jmp(long addr
)
1018 os("\xe9", 1); /* jmp $addr */
1019 oi(addr
- codeaddr() - 4, 4);
1020 return codeaddr() - 4;
1023 void o_filljmp2(long addr
, long jmpdst
)
1025 putint(buf
+ addr
, jmpdst
- addr
- 4, 4);
1028 void o_filljmp(long addr
)
1030 o_filljmp2(addr
, codeaddr());
1033 void o_call(int argc
, unsigned *bt
, unsigned ret_bt
)
1037 for (i
= 0; i
< ARRAY_SIZE(tmpregs
); i
++)
1038 if (regs
[tmpregs
[i
]] && regs
[tmpregs
[i
]] - tmps
< ntmp
- argc
)
1039 tmp_mem(regs
[tmpregs
[i
]]);
1040 sp_push(LONGSZ
* argc
);
1041 for (i
= argc
- 1; i
>= 0; --i
) {
1042 int reg
= TMP_REG(TMP(0));
1043 tmp_pop(reg
, TMPBT(bt
[i
]));
1044 op_rm(I_MOV
, reg
, R_ESP
, i
* LONGSZ
, TMPBT(bt
[i
]));
1047 if (t
->flags
& LOC_SYM
) {
1048 os("\xe8", 1); /* call $x */
1050 out_rela(t
->addr
, codeaddr(), 1);
1056 op_rr(I_CALL
, 2, R_EAX
, 4);
1059 tmp_push(R_EAX
, ret_bt
);
1072 void o_datset(long addr
, int off
, unsigned bt
)
1074 struct tmp
*t
= TMP(0);
1075 if (t
->flags
& LOC_NUM
&& !(t
->flags
& TMP_ADDR
)) {
1077 out_datcpy(addr
, off
, (void *) &t
->addr
, BT_SZ(bt
));
1079 if (t
->flags
& LOC_SYM
&& !(t
->flags
& TMP_ADDR
)) {
1080 out_datrela(t
->addr
, addr
, off
);
1081 out_datcpy(addr
, off
, (void *) &t
->off
, BT_SZ(bt
));