*** sim/h8300/compile.c.original Wed Feb 19 15:28:09 2003 --- sim/h8300/compile.c.modified Sat Feb 22 19:50:43 2003 *************** void sim_set_simcache_size PARAMS ((int) *** 119,124 **** --- 119,132 ---- #define UEXTSHORT(x) ((x) & 0xffff) #define SEXTSHORT(x) ((short) (x)) + #define SET_CMDLINE_LOCATION \ + if (h8300smode) \ + addr_cmdline = 0xffff00L; \ + else if (h8300hmode) \ + addr_cmdline = 0x2ff00L; \ + else \ + addr_cmdline = 0xff00L; + static cpu_state_type cpu; int h8300hmode = 0; *************** decode (int addr, unsigned char *data, d *** 447,460 **** dst->opcode = q->how; dst->cycles = q->time; ! /* And a jsr to 0xc4 is turned into a magic trap. */ if (dst->opcode == O (O_JSR, SB)) { ! if (dst->src.literal == 0xc4) { dst->opcode = O (O_SYSCALL, SB); } } dst->next_pc = addr + len / 2; --- 455,475 ---- dst->opcode = q->how; dst->cycles = q->time; ! /* And a jsr to these locations are turned into magic ! traps. */ if (dst->opcode == O (O_JSR, SB)) { ! switch (dst->src.literal) { + case 0xc4: dst->opcode = O (O_SYSCALL, SB); + break; + case 0xcc: + dst->opcode = O (O_SYS_CMDLINE, SB); + break; } + /* End of Processing for system calls. */ } dst->next_pc = addr + len / 2; *************** sim_resume (SIM_DESC sd, int step, int s *** 1389,1394 **** --- 1404,1562 ---- sim_callback->write_stdout (sim_callback, &c, 1); } goto next; + + /* Trap for Command Line setup. */ + case O (O_SYS_CMDLINE, SB): + { + int i = 0; /* Loop counter. */ + int j = 0; /* Loop counter. */ + int ind_arg_len = 0; /* Length of each argument. */ + int no_of_args = 0; /* The no. or cmdline args. */ + int current_location = 0; /* Location of string. */ + int old_sp = 0; /* The Initial Stack Pointer. */ + int no_of_slots = 0; /* No. of slots required on the stack + for storing cmdline args. */ + int sp_move = 0; /* No. of locations by which the stack needs + to grow. */ + int new_sp = 0; /* The final stack pointer location passed + back. */ + int *argv_ptrs; /* Pointers of argv strings to be stored. */ + int argv_ptrs_location = 0; /* Location of pointers to cmdline + args on the stack. */ + int char_ptr_size = 0; /* Size of a character pointer on + target machine. */ + int addr_cmdline = 0; /* Memory location where cmdline has + to be stored. */ + int size_cmdline = 0; /* Size of cmdline. */ + + /* Set the address of 256 free locations where command line is + stored. */ + SET_CMDLINE_LOCATION + + cpu.regs[0] = addr_cmdline; + + /* Counting the no. of commandline arguments. */ + for (i = 0; ptr_CommandLine[i] != NULL; i++) + continue; + + /* No. of arguments in the command line. */ + no_of_args = i; + + /* Current location is just a temporary variable,which we are + setting to the point to the start of our commandline string. */ + current_location = addr_cmdline; + + /* Allocating space for storing pointers of the command line + arguments. */ + argv_ptrs = (int *) malloc (sizeof (int) * no_of_args); + + /* Setting char_ptr_size to the sizeof (char *) on the different + architectures. */ + if (h8300hmode || h8300smode) + { + char_ptr_size = 4; + } + else + { + char_ptr_size = 2; + } + + for (i = 0; i < no_of_args; i++) + { + ind_arg_len = 0; + + /* The size of the commandline argument. */ + ind_arg_len = (strlen (ptr_CommandLine[i]) + 1); + + /* The total size of the command line string. */ + size_cmdline += ind_arg_len; + + /* As we have only 256 bytes, we need to provide a graceful + exit. Anyways, a program using command line arguments + where we cannot store all the command line arguments + given may behave unpredictably. */ + if (size_cmdline >= 256) + { + cpu.regs[0] = 0; + goto next; + } + else + { + /* current_location points to the memory where the next + commandline argument is stored. */ + argv_ptrs[i] = current_location; + for (j = 0; j < ind_arg_len; j++) + { + SET_MEMORY_B ((current_location + + (sizeof (char) * j)), + *(ptr_CommandLine[i] + + sizeof (char) * j)); + } + + /* Setting current_location to the starting of next + argument. */ + current_location += ind_arg_len; + } + } + + /* This is the original position of the stack pointer. */ + old_sp = cpu.regs[7]; + + /* We need space from the stack to store the pointers to argvs. */ + /* As we will infringe on the stack, we need to shift the stack + pointer so that the data is not overwritten. We calculate how + much space is required. */ + sp_move = (no_of_args) * (char_ptr_size); + + /* The final position of stack pointer, we have thus taken some + space from the stack. */ + new_sp = old_sp - sp_move; + + /* Temporary variable holding value where the argv pointers need + to be stored. */ + argv_ptrs_location = new_sp; + + /* The argv pointers are stored at sequential locations. As per + the H8300 ABI. */ + for (i = 0; i < no_of_args; i++) + { + /* Saving the argv pointer. */ + if (h8300hmode || h8300smode) + { + SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]); + } + else + { + SET_MEMORY_W (argv_ptrs_location, argv_ptrs[i]); + } + + /* The next location where the pointer to the next argv + string has to be stored. */ + argv_ptrs_location += char_ptr_size; + } + + /* Required by POSIX, Setting 0x0 at the end of the list of argv + pointers. */ + if (h8300hmode || h8300smode) + { + SET_MEMORY_L (old_sp, 0x0); + } + else + { + SET_MEMORY_W (old_sp, 0x0); + } + + /* Freeing allocated memory. */ + free (argv_ptrs); + + /* The no. of argv arguments are returned in Reg 0. */ + cpu.regs[0] = no_of_args; + /* The Pointer to argv in Register 1. */ + cpu.regs[1] = new_sp; + /* Setting the stack pointer to the new value. */ + cpu.regs[7] = new_sp; + } + goto next; ONOT (O_NOT, rd = ~rd; v = 0;); OSHIFTS (O_SHLL, *************** sim_create_inferior (SIM_DESC sd, struct *** 2231,2236 **** --- 2399,2411 ---- cpu.pc = bfd_get_start_address (abfd); else cpu.pc = 0; + + /* Command Line support. */ + if (argv != NULL) + { + ptr_CommandLine = argv; + } + return SIM_RC_OK; }