1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
  
9
  
10
  
11
  
12
  
13
  
14
  
15
  
16
  
17
  
18
  
19
  
20
  
21
  
22
  
23
  
24
  
25
  
26
  
27
  
28
  
29
  
30
  
31
  
32
  
33
  
34
  
35
  
36
  
37
  
38
  
39
  
40
  
41
  
42
  
43
  
44
  
45
  
46
  
47
  
48
  
49
  
50
  
51
  
52
  
53
  
54
  
55
  
56
  
57
  
58
  
59
  
60
  
61
  
62
  
63
  
64
  
65
  
66
  
67
  
68
  
69
  
70
  
71
  
72
  
73
  
74
  
75
  
76
  
77
  
78
  
79
  
80
  
81
  
82
  
83
  
84
  
85
  
86
  
87
  
88
  
89
  
90
  
91
  
92
  
93
  
94
  
95
  
96
  
97
  
98
  
99
  
100
  
101
  
102
  
103
  
104
  
105
  
106
  
107
  
108
  
109
  
110
  
111
  
112
  
113
  
114
  
115
  
116
  
117
  
118
  
119
  
120
  
/* 
 * $Id: sparc.c,v 1.3 2001/07/20 16:21:32 grubba Exp $ 
 * 
 * Machine code generator for sparc. 
 * 
 * Henrik Grubbström 20010720 
 */ 
 
#define CALL_ABSOLUTE(X) do {                                         \ 
    INT32 delta_;                                                       \ 
    struct program *p_ = Pike_compiler->new_program;                    \ 
    INT32 off_ = p_->num_program;                                       \ 
    /* call X   */                                                      \ 
    add_to_program(0); /* Placeholder... */                             \ 
    delta_ = ((PIKE_OPCODE_T *)(X)) - (p_->program + off_);             \ 
    p_->program[off_] = 0x40000000 | (delta_ & 0x3fffffff);             \ 
    add_to_relocations(off_);                                           \ 
    /* noop             */                                              \ 
    add_to_program(0x01000000);                                         \ 
  } while(0) 
 
void ins_f_byte(unsigned int b) 
{ 
#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 
     
  do{ 
    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(); 
    } 
  }while(0); 
   
  CALL_ABSOLUTE(instrs[b].address); 
  return; 
} 
 
void ins_f_byte_with_arg(unsigned int a,unsigned INT32 b) 
{ 
  SET_REG(REG_O0, b); 
  ins_f_byte(a); 
  return; 
} 
 
void ins_f_byte_with_2_args(unsigned int a, 
                            unsigned INT32 c, 
                            unsigned INT32 b) 
{ 
  SET_REG(REG_O0, c); 
  SET_REG(REG_O1, b); 
  ins_f_byte(a); 
  return; 
} 
 
#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; 
  /* De-relocate the program... */ 
  for (rel = 0; rel < p->num_relocations; rel++) { 
    size_t off = p->relocations[rel]; 
    INT32 opcode; 
#ifdef PIKE_DEBUG 
    if (off < prev) { 
      fatal("Relocations in bad order!\n"); 
    } 
#endif /* PIKE_DEBUG */ 
    adddata2(p->program + prev, off - prev); 
 
#ifdef PIKE_DEBUG 
    if ((p->program[off] & 0xc0000000) != 0x40000000) { 
      fatal("Bad relocation!\n"); 
    } 
#endif /* PIKE_DEBUG */ 
    /* Relocate to being relative to NULL */ 
    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) 
{ 
  /* Relocate the program... */ 
  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); 
  } 
#endif /* sparc */ 
}