dd6bca | 2001-07-20 | Henrik Grubbström (Grubba) | | |
5aad93 | 2002-08-15 | Marcus Comstedt | | * $Id: sparc.c,v 1.11 2002/08/15 14:50:24 marcus Exp $
|
dd6bca | 2001-07-20 | Henrik Grubbström (Grubba) | | *
* Machine code generator for sparc.
*
* Henrik Grubbström 20010720
*/
|
fc3100 | 2001-07-24 | Henrik Grubbström (Grubba) | | #include "operators.h"
|
f1d1eb | 2001-07-20 | Henrik Grubbström (Grubba) | | #define ADD_CALL(X, DELAY_OK) do { \
|
dd6bca | 2001-07-20 | Henrik Grubbström (Grubba) | | INT32 delta_; \
struct program *p_ = Pike_compiler->new_program; \
INT32 off_ = p_->num_program; \
|
f1d1eb | 2001-07-20 | Henrik Grubbström (Grubba) | | /* noop */ \
INT32 delay_ = 0x01000000; \
\
if (DELAY_OK) { \
/* Move the previous opcode to the delay-slot. */ \
delay_ = p_->program[--off_]; \
} else { \
add_to_program(0); /* Placeholder... */ \
} \
|
dd6bca | 2001-07-20 | Henrik Grubbström (Grubba) | | /* call X */ \
delta_ = ((PIKE_OPCODE_T *)(X)) - (p_->program + off_); \
p_->program[off_] = 0x40000000 | (delta_ & 0x3fffffff); \
add_to_relocations(off_); \
|
f1d1eb | 2001-07-20 | Henrik Grubbström (Grubba) | | add_to_program(delay_); \
|
dd6bca | 2001-07-20 | Henrik Grubbström (Grubba) | | } while(0)
|
f1d1eb | 2001-07-20 | Henrik Grubbström (Grubba) | | static void low_ins_f_byte(unsigned int b, int delay_ok)
|
dd6bca | 2001-07-20 | Henrik Grubbström (Grubba) | | {
|
11ed4b | 2001-07-24 | Henrik Grubbström (Grubba) | | void *addr;
|
fc3100 | 2001-07-24 | Henrik Grubbström (Grubba) | |
|
dd6bca | 2001-07-20 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
if(store_linenumbers && b<F_MAX_OPCODE)
ADD_COMPILED(b);
#endif /* PIKE_DEBUG */
b-=F_OFFSET;
#ifdef PIKE_DEBUG
if(b>255)
Pike_error("Instruction too big %d\n",b);
#endif
|
f1d1eb | 2001-07-20 | Henrik Grubbström (Grubba) | | {
|
dd6bca | 2001-07-20 | Henrik Grubbström (Grubba) | | static int last_prog_id=-1;
static int last_num_linenumbers=-1;
if(last_prog_id != Pike_compiler->new_program->id ||
last_num_linenumbers != Pike_compiler->new_program->num_linenumbers)
{
last_prog_id=Pike_compiler->new_program->id;
last_num_linenumbers = Pike_compiler->new_program->num_linenumbers;
UPDATE_PC();
|
f1d1eb | 2001-07-20 | Henrik Grubbström (Grubba) | | delay_ok = 1;
|
dd6bca | 2001-07-20 | Henrik Grubbström (Grubba) | | }
|
f1d1eb | 2001-07-20 | Henrik Grubbström (Grubba) | | }
|
fc3100 | 2001-07-24 | Henrik Grubbström (Grubba) | |
|
11ed4b | 2001-07-24 | Henrik Grubbström (Grubba) | | addr = instrs[b].address;
|
9a928d | 2002-05-10 | Martin Stjernholm | | #ifdef PIKE_DEBUG
if (d_flag < 3)
#endif
|
fc3100 | 2001-07-24 | Henrik Grubbström (Grubba) | |
switch(b)
{
case F_MAKE_ITERATOR - F_OFFSET:
{
extern void f_Iterator(INT32);
SET_REG(SPARC_REG_O0, 1);
delay_ok = 1;
addr = (void *)f_Iterator;
}
break;
case F_ADD - F_OFFSET:
SET_REG(SPARC_REG_O0, 2);
delay_ok = 1;
addr = (void *)f_add;
break;
}
|
9a928d | 2002-05-10 | Martin Stjernholm | |
|
11ed4b | 2001-07-24 | Henrik Grubbström (Grubba) | | ADD_CALL(addr, delay_ok);
|
f1d1eb | 2001-07-20 | Henrik Grubbström (Grubba) | | }
void ins_f_byte(unsigned int opcode)
{
low_ins_f_byte(opcode, 0);
|
dd6bca | 2001-07-20 | Henrik Grubbström (Grubba) | | }
void ins_f_byte_with_arg(unsigned int a,unsigned INT32 b)
{
|
7df348 | 2001-07-21 | Henrik Grubbström (Grubba) | | SET_REG(SPARC_REG_O0, b);
|
f1d1eb | 2001-07-20 | Henrik Grubbström (Grubba) | | low_ins_f_byte(a, 1);
|
dd6bca | 2001-07-20 | Henrik Grubbström (Grubba) | | return;
}
void ins_f_byte_with_2_args(unsigned int a,
unsigned INT32 c,
unsigned INT32 b)
{
|
7df348 | 2001-07-21 | Henrik Grubbström (Grubba) | | SET_REG(SPARC_REG_O0, c);
SET_REG(SPARC_REG_O1, b);
|
f1d1eb | 2001-07-20 | Henrik Grubbström (Grubba) | | low_ins_f_byte(a, 1);
|
dd6bca | 2001-07-20 | Henrik Grubbström (Grubba) | | return;
}
|
697e0a | 2001-07-20 | Henrik Grubbström (Grubba) | |
#define addstr(s, l) low_my_binary_strcat((s), (l), buf)
#define adddata2(s,l) addstr((char *)(s),(l) * sizeof((s)[0]));
void sparc_encode_program(struct program *p, struct dynamic_buffer_s *buf)
{
size_t prev = 0, rel;
for (rel = 0; rel < p->num_relocations; rel++) {
size_t off = p->relocations[rel];
INT32 opcode;
#ifdef PIKE_DEBUG
if (off < prev) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Relocations in bad order!\n");
|
697e0a | 2001-07-20 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_DEBUG */
adddata2(p->program + prev, off - prev);
#ifdef PIKE_DEBUG
if ((p->program[off] & 0xc0000000) != 0x40000000) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Bad relocation!\n");
|
697e0a | 2001-07-20 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_DEBUG */
opcode = 0x40000000 |
((p->program[off] + (((INT32)(p->program)>>2))) & 0x3fffffff);
adddata2(&opcode, 1);
prev = off+1;
}
adddata2(p->program + prev, p->num_program - prev);
}
void sparc_decode_program(struct program *p)
{
PIKE_OPCODE_T *prog = p->program;
INT32 delta = ((INT32)p->program)>>2;
size_t rel = p->num_relocations;
while (rel--) {
#ifdef PIKE_DEBUG
if ((prog[p->relocations[rel]] & 0xc0000000) != 0x40000000) {
Pike_error("Bad relocation: %d, off:%d, opcode: 0x%08x\n",
rel, p->relocations[rel],
prog[p->relocations[rel]]);
}
#endif /* PIKE_DEBUG */
prog[p->relocations[rel]] = 0x40000000 |
(((prog[p->relocations[rel]] & 0x3fffffff) - delta) &
0x3fffffff);
}
}
|
9d2e2d | 2001-07-21 | Henrik Grubbström (Grubba) | |
const unsigned INT32 sparc_flush_instruction_cache[] = {
0x80a02000|(SPARC_REG_O1<<14)|1,
0x81d80000|(SPARC_REG_O0<<14)|(SPARC_REG_O1),
0x36800000|((-1)&0x3fffff),
0x80a02000|(SPARC_REG_O1<<25)|(SPARC_REG_O1<<14)|8,
0x81c02000|(SPARC_REG_O7<<14)|8,
0x80100000|(SPARC_REG_O0<<25),
};
|