static int arg (int bytes) { int rv = 0; argp++; if (A16) { switch (argp) { case 1: if (bytes == 1) return get_reg (r1l); if (bytes == 2) return get_reg (r1); break; case 2: if (bytes == 2) return get_reg (r2); break; } } else { switch (argp) { case 1: if (bytes == 1) return get_reg (r0l); if (bytes == 2) return get_reg (r0); break; } } if (bytes == 0) bytes = 2; switch (bytes) { case 1: rv = mem_get_qi (get_reg (sp) + stackp); if (A24) stackp++; break; case 2: rv = mem_get_hi (get_reg (sp) + stackp); break; case 3: rv = mem_get_psi (get_reg (sp) + stackp); if (A24) stackp++; break; case 4: rv = mem_get_si (get_reg (sp) + stackp); break; } stackp += bytes; return rv; }
static int arg () { int rv = 0; argp++; if (argp < 4) return get_reg (argp); rv = mem_get_si (get_reg (sp) + stackp); stackp += 4; return rv; }
int get_src (srcdest sd) { int v; if (sd.mem) { switch (sd.bytes) { case 1: v = mem_get_qi (sd.u.addr); break; case 2: v = mem_get_hi (sd.u.addr); break; case 3: v = mem_get_psi (sd.u.addr); break; case 4: v = mem_get_si (sd.u.addr); break; default: abort (); } } else { v = get_reg (sd.u.reg); switch (sd.bytes) { case 1: v &= 0xff; break; case 2: v &= 0xffff; break; case 3: v &= 0xffffff; break; } } return v; }
static srcdest decode_sd23 (int bbb, int bb, int bytes, int ind, int add) { srcdest sd; int code = (bbb << 2) | bb; if (code >= sizeof (modes23) / sizeof (modes23[0])) abort (); if (trace) { char *b1 = ""; char *b2 = ""; char ad[30]; if (ind) { b1 = "["; b2 = "]"; } if (add) sprintf (ad, "%+d", add); else ad[0] = 0; if (!the_bits) the_bits = bits (code, 4); printf ("decode: %s (%d) : %s%s%s%s\n", the_bits, code, b1, modes23[code].name, ad, b2); the_bits = 0; } sd.bytes = bytes; sd.mem = modes23[code].is_memory; if (sd.mem) { if (modes23[code].w_regno == mem) sd.u.addr = 0; else sd.u.addr = get_reg (modes23[code].w_regno); switch (modes23[code].disp_bytes) { case 1: sd.u.addr += disp8 (); break; case 2: sd.u.addr += disp16 (); break; case -1: sd.u.addr += sign_ext (disp8 (), 8); break; case -2: sd.u.addr += sign_ext (disp16 (), 16); break; case 3: sd.u.addr += disp24 (); break; default: break; } if (add) sd.u.addr += add; if (ind) sd.u.addr = mem_get_si (sd.u.addr & membus_mask); sd.u.addr &= membus_mask; } else { sd.u.reg = (bytes > 1) ? modes23[code].w_regno : modes23[code].b_regno; if (bytes == 3 || bytes == 4) { switch (sd.u.reg) { case r0: sd.u.reg = r2r0; break; case r1: sd.u.reg = r3r1; break; case r2: abort (); case r3: abort (); default:; } } } return sd; }
void rx_load (bfd *prog) { unsigned long highest_addr_loaded = 0; Elf_Internal_Phdr * phdrs; long sizeof_phdrs; int num_headers; int i; rx_big_endian = bfd_big_endian (prog); /* Note we load by ELF program header not by BFD sections. This is because BFD sections get their information from the ELF section structure, which only includes a VMA value and not an LMA value. */ sizeof_phdrs = bfd_get_elf_phdr_upper_bound (prog); if (sizeof_phdrs == 0) { fprintf (stderr, "Failed to get size of program headers\n"); return; } phdrs = malloc (sizeof_phdrs); if (phdrs == NULL) { fprintf (stderr, "Failed allocate memory to hold program headers\n"); return; } num_headers = bfd_get_elf_phdrs (prog, phdrs); if (num_headers < 1) { fprintf (stderr, "Failed to read program headers\n"); return; } for (i = 0; i < num_headers; i++) { Elf_Internal_Phdr * p = phdrs + i; char *buf; bfd_vma size; bfd_vma base; file_ptr offset; size = p->p_filesz; if (size <= 0) continue; base = p->p_paddr; if (verbose > 1) fprintf (stderr, "[load segment: lma=%08x vma=%08x size=%08x]\n", (int) base, (int) p->p_vaddr, (int) size); buf = malloc (size); if (buf == NULL) { fprintf (stderr, "Failed to allocate buffer to hold program segment\n"); continue; } offset = p->p_offset; if (prog->iovec->bseek (prog, offset, SEEK_SET) != 0) { fprintf (stderr, "Failed to seek to offset %lx\n", (long) offset); continue; } if (prog->iovec->bread (prog, buf, size) != size) { fprintf (stderr, "Failed to read %lx bytes\n", size); continue; } mem_put_blk (base, buf, size); free (buf); if (highest_addr_loaded < base + size - 1 && size >= 4) highest_addr_loaded = base + size - 1; } free (phdrs); regs.r_pc = prog->start_address; if (strcmp (bfd_get_target (prog), "srec") == 0 || regs.r_pc == 0) { regs.r_pc = mem_get_si (0xfffffffc); heaptop = heapbottom = 0; } if (verbose > 1) fprintf (stderr, "[start pc=%08x %s]\n", (unsigned int) regs.r_pc, rx_big_endian ? "BE" : "LE"); }
void m32c_load (bfd * prog) { asection *s; unsigned long mach = bfd_get_mach (prog); unsigned long highest_addr_loaded = 0; if (mach == 0 && default_machine != 0) mach = default_machine; m32c_set_mach (mach); for (s = prog->sections; s; s = s->next) { #if 0 /* This was a good idea until we started storing the RAM data in ROM, at which point everything was all messed up. The code remains as a reminder. */ if ((s->flags & SEC_ALLOC) && !(s->flags & SEC_READONLY)) { if (strcmp (bfd_get_section_name (prog, s), ".stack")) { int secend = bfd_get_section_size (s) + bfd_section_lma (prog, s); if (heaptop < secend && bfd_section_lma (prog, s) < 0x10000) { heaptop = heapbottom = secend; } } } #endif if (s->flags & SEC_LOAD) { char *buf; bfd_size_type size; size = bfd_get_section_size (s); if (size <= 0) continue; bfd_vma base = bfd_section_lma (prog, s); if (verbose) fprintf (stderr, "[load a=%08x s=%08x %s]\n", (int) base, (int) size, bfd_get_section_name (prog, s)); buf = (char *) malloc (size); bfd_get_section_contents (prog, s, buf, 0, size); mem_put_blk (base, buf, size); free (buf); if (highest_addr_loaded < base + size - 1 && size >= 4) highest_addr_loaded = base + size - 1; } } if (strcmp (bfd_get_target (prog), "srec") == 0) { heaptop = heapbottom = 0; switch (mach) { case bfd_mach_m16c: if (highest_addr_loaded > 0x10000) regs.r_pc = mem_get_si (0x000ffffc) & membus_mask; else regs.r_pc = mem_get_si (0x000fffc) & membus_mask; break; case bfd_mach_m32c: regs.r_pc = mem_get_si (0x00fffffc) & membus_mask; break; } } else regs.r_pc = prog->start_address; if (verbose) fprintf (stderr, "[start pc=%08x]\n", (unsigned int) regs.r_pc); }