⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asm.c

📁 gdb for adsp develop
💻 C
📖 第 1 页 / 共 4 页
字号:
static char _[] = " @(#)asm.c	5.23 93/10/26 10:17:03, Srini, AMD";/****************************************************************************** * Copyright 1991 Advanced Micro Devices, Inc. * * This software is the property of Advanced Micro Devices, Inc  (AMD)  which * specifically  grants the user the right to modify, use and distribute this * software provided this notice is not removed or altered.  All other rights * are reserved by AMD. * * AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS * SOFTWARE.  IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL * DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR * USE OF THIS SOFTWARE. * * So that all may benefit from your experience, please report  any  problems * or  suggestions about this software to the 29K Technical Support Center at * 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131  in  the  UK,  or * 0031-11-1129 in Japan, toll free.  The direct dial number is 512-462-4118. * * Advanced Micro Devices, Inc. * 29K Support Products * Mail Stop 573 * 5900 E. Ben White Blvd. * Austin, TX 78741 * 800-292-9263 ***************************************************************************** *      Engineer: Srini Subramanian. ***************************************************************************** * This module supports the assemble command to assemble 29K instructions * in memory. ***************************************************************************** */#include <stdio.h>#include "opcodes.h"#include "memspcs.h"#include "main.h"#include "monitor.h"#include "macros.h"#include "miniint.h"#include "error.h"#ifdef	MSDOS#include <string.h>#define	strcasecmp	stricmp#else#include <string.h>#endif/*** There are approximately 23 different instruction formats for the** Am29000.  Instructions are assembled using one of these formats.**** Note:  Opcodes in the "switch" statement are sorted in numerical**        order.***/int  	get_addr_29k_m PARAMS((char *, struct addr_29k_t *, INT32));int  	addr_29k_ok PARAMS((struct addr_29k_t *));void 	convert32 PARAMS((BYTE *));int  	set_data PARAMS((BYTE *, BYTE *, int));int  asm_instr PARAMS((struct instr_t *, char **, int));int  asm_arith_logic PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_load_store PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_vector PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_no_parms PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_one_parms PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_float PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_call_jmp PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_calli_jmpi PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_class PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_clz PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_const PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_consth PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_convert PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_div0 PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_exhws PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_jmp PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_jmpi PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_mfsr PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_mtsr PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_mtsrim PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_mftlb PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_mttlb PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_sqrt PARAMS((struct instr_t *, struct addr_29k_t *, int));int  asm_emulate PARAMS((struct instr_t *, struct addr_29k_t *, int));extern	void	Mini_poll_kbd PARAMS((char  *cmd_buffer, int size, int mode));extern	int	Mini_cmdfile_input PARAMS((char  *cmd_buffer, int size));extern	int   	tokenize_cmd PARAMS((char *, char **));extern 	void 	lcase_tokens PARAMS((char **, int));extern	INT32 	do_assemble PARAMS(( struct addr_29k_t	addr_29k,				     char	*token[],				     int	token_count));#ifndef XRAYextern 	char  	cmd_buffer[];#define	MAX_ASM_TOKENS	15static	char	*asm_token[MAX_ASM_TOKENS];static	int	asm_token_count;/*** This function is used to assemble an instruction.  The command** takes as parameters an array of strings (*token[]) and a** count (token_count) which gives the number of tokens in the** array.  These tokens should have the following values:**** token[0] - 'a' (the assemble command)** token[1] - <address> (the address to assemble instruction at)** token[2] - <opcode>  (the 29K opcode nmemonic)** token[3] to token[n] - parameters to the assembly instruction.***/INT32asm_cmd(token, token_count)   char   *token[];   int     token_count;   {   INT32		result;   struct addr_29k_t 	addr_29k;   int		asm_done;   /*   ** Parse parameters   */   if ((token_count < 2) || (token_count > 9)) {      return (EMSYNTAX);   } else if (token_count == 2) {      /* Get address of assembly */      result = get_addr_29k_m(token[1], &addr_29k, I_MEM);      if (result != 0)         return (result);      result = addr_29k_ok(&addr_29k);      if (result != 0)         return (result);      asm_done = 0;      fprintf(stderr, "0x%08lx:\t", addr_29k.address);      do {        if (io_config.cmd_file_io == TRUE) {	     if (Mini_cmdfile_input(cmd_buffer, BUFFER_SIZE) == SUCCESS) {               fprintf(stderr, "%s", cmd_buffer); 	     } else {               Mini_poll_kbd(cmd_buffer, BUFFER_SIZE, BLOCK); /* block */	     }	} else {             Mini_poll_kbd(cmd_buffer, BUFFER_SIZE, BLOCK); /* block */	}	if (io_config.log_file)  /* make a log file */#ifdef	MSDOS            fprintf(io_config.log_file, "%s\n", cmd_buffer);#else            fprintf(io_config.log_file, "%s", cmd_buffer);#endif     	if (io_config.echo_mode == (INT32) TRUE)#ifdef	MSDOS            fprintf(io_config.echo_file, "%s\n", cmd_buffer);#else            fprintf(io_config.echo_file, "%s", cmd_buffer);#endif        asm_token_count = tokenize_cmd(cmd_buffer, asm_token);        lcase_tokens(asm_token, asm_token_count);	if (strcmp(token[0], ".") == 0)	  asm_done = 1;	else {          result= do_assemble(addr_29k, &asm_token[0], asm_token_count);	  if (result != SUCCESS)	    warning (result);	  else	    addr_29k.address = addr_29k.address + 4;	  fprintf(stderr, "0x%08lx:\t", addr_29k.address);	}      } while (asm_done != 1);   } else {      /* Get address of assembly */      result = get_addr_29k_m(token[1], &addr_29k, I_MEM);      if (result != 0)         return (result);      result = addr_29k_ok(&addr_29k);      if (result != 0)         return (result);      return (do_assemble(addr_29k, &token[2], (token_count-2)));   }   return (SUCCESS);}INT32do_assemble(addr_29k, token, token_count)struct addr_29k_t	addr_29k;char			*token[];int			token_count;{   INT32    result;   struct instr_t    instr;   INT32	retval;   BYTE		*write_data;   INT32	bytes_ret;   INT32	hostendian;	/* for UDI conformant */   /* Initialize instr */   instr.op = 0;   instr.c  = 0;   instr.a  = 0;   instr.b  = 0;   /* Assemble instruction */   result = asm_instr(&instr, &(token[0]), token_count);   if (result != 0)      return (EMSYNTAX);   /* Will the data overflow the message buffer?  done in TIP */   write_data = (BYTE *) &instr;   hostendian = FALSE;   if ((retval = Mini_write_req (addr_29k.memory_space,				 addr_29k.address, 				 1, /* count */				 (INT16) sizeof(INST32),  /* size */				 &bytes_ret,				 write_data,				 hostendian)) != SUCCESS) {      return(FAILURE);   };    return (SUCCESS);}#endif/*** This function is used to assemble a single Am29000 instruction.** The token[] array contains the lower-case tokens for a single** assembler instruction.  The token_count contains the number of** tokens in the array.  This number should be at least 1 (as in the** cases of instructions like IRET) and at most 5 (for instructions** like LOAD).*/#ifdef XRAY  extern struct t_inst_table {	char  *inst_mnem;	unsigned char	oprn_fmt;} inst_table[];#endifintasm_instr(instr, token, token_count)   struct   instr_t *instr;   char    *token[];   int      token_count;   {   int    i;   int    result;   struct addr_29k_t parm[10];   char   temp_opcode[20];   char  *temp_ptr;   int    opcode_found;   static char  *str_0x40="0x40";   static char  *str_gr1="gr1";   /* Is token_count valid, and is the first token a string? */   if ((token_count < 1) ||       (token_count > 7) ||       (strcmp(token[0], "") == 0))      return (EMSYNTAX);   /* Get opcode */   /*   ** Note:  Since the opcode_name[] string used in the disassembler   ** uses padded strings, we cannot do a strcmp().  We canot do a   ** strncmp() of the length of token[0] either, since "and" will   ** match up (for instance) with "andn".  So we copy the string,   ** null terminate at the first pad character (space), and then   ** compare.  This is inefficient, but necessary.   */   i=0;   opcode_found = FALSE;   while ((i<256) && (opcode_found != TRUE)) {#ifdef XRAY      result = strcasecmp(token[0], inst_table[i].inst_mnem);#else      temp_ptr = strcpy(temp_opcode, opcode_name[i]);      if (strcmp(temp_ptr, "") != 0)         temp_ptr = strtok(temp_opcode, " ");      result = strcmp(token[0], temp_ptr);#endif      if (result == 0) {         opcode_found = TRUE;         instr->op = (BYTE) i;         }      i = i + 1;      }  /* end while */   /* Check for a NOP */   if ((opcode_found == FALSE) &&       (strcasecmp(token[0], "nop") == 0)) {      opcode_found = TRUE;      instr->op = ASEQ0;      /* Fake up tokens to give "aseq 0x40,gr1,gr1" */      token_count = 4;      token[1] = str_0x40;      token[2] = str_gr1;      token[3] = str_gr1;      }   if (opcode_found == FALSE)      return (EMSYNTAX);   if ((strcasecmp(token[0], "iretinv") == 0) ||       (strcasecmp(token[0], "inv") == 0) ) {       /* iretinv and inv instructions */      for (i=1; i<token_count; i=i+1) {         result = get_addr_29k_m(token[i], &(parm[i-1]), GENERIC_SPACE);         if (result != 0)            return (result);      }   } else {   /* Make the other tokens into addr_29k */   for (i=1; i<token_count; i=i+1) {      result = get_addr_29k_m(token[i], &(parm[i-1]), I_MEM);      if (result != 0)         return (result);      /* Check if register values are legal */      if (ISREG(parm[i-1].memory_space)) {         result = addr_29k_ok(&(parm[i-1]));         if (result != 0)            return (EMBADREG);         }      /* Set bit 7 if a LOCAL_REG */      if (parm[i-1].memory_space == LOCAL_REG)         parm[i-1].address = (parm[i-1].address | 0x80);      }   }   switch (instr->op) {         /* Opcodes 0x00 to 0x0F */      case ILLEGAL_00:  result = EMSYNTAX;                        break;      case CONSTN:      result = asm_const(instr, parm, 2);                        break;      case CONSTH:      result = asm_consth(instr, parm, 2);                        break;      case CONST:       result = asm_const(instr, parm, 2);                        break;      case MTSRIM:      result = asm_mtsrim(instr, parm, 2);                        break;      case CONSTHZ:     result = asm_const(instr, parm, 2);                        break;      case LOADL0:      result = asm_load_store(instr, parm, 4);                        break;      case LOADL1:      result = asm_load_store(instr, parm, 4);                        break;      case CLZ0:        result = asm_clz(instr, parm, 2);                        break;      case CLZ1:        result = asm_clz(instr, parm, 2);                        break;      case EXBYTE0:     result = asm_arith_logic(instr, parm, 3);                        break;      case EXBYTE1:     result = asm_arith_logic(instr, parm, 3);                        break;      case INBYTE0:     result = asm_arith_logic(instr, parm, 3);                        break;      case INBYTE1:     result = asm_arith_logic(instr, parm, 3);                        break;      case STOREL0:     result = asm_load_store(instr, parm, 4);                        break;      case STOREL1:     result = asm_load_store(instr, parm, 4);                        break;      /* Opcodes 0x10 to 0x1F */      case ADDS0:       result = asm_arith_logic(instr, parm, 3);                        break;      case ADDS1:       result = asm_arith_logic(instr, parm, 3);                        break;      case ADDU0:       result = asm_arith_logic(instr, parm, 3);                        break;      case ADDU1:       result = asm_arith_logic(instr, parm, 3);                        break;      case ADD0:        result = asm_arith_logic(instr, parm, 3);                        break;      case ADD1:        result = asm_arith_logic(instr, parm, 3);                        break;      case LOAD0:       result = asm_load_store(instr, parm, 4);                        break;      case LOAD1:       result = asm_load_store(instr, parm, 4);                        break;      case ADDCS0:      result = asm_arith_logic(instr, parm, 3);                        break;      case ADDCS1:      result = asm_arith_logic(instr, parm, 3);                        break;      case ADDCU0:      result = asm_arith_logic(instr, parm, 3);                        break;      case ADDCU1:      result = asm_arith_logic(instr, parm, 3);                        break;      case ADDC0:       result = asm_arith_logic(instr, parm, 3);                        break;      case ADDC1:       result = asm_arith_logic(instr, parm, 3);                        break;      case STORE0:      result = asm_load_store(instr, parm, 4);                        break;      case STORE1:      result = asm_load_store(instr, parm, 4);                        break;      /* Opcodes 0x20 to 0x2F */      case SUBS0:       result = asm_arith_logic(instr, parm, 3);                        break;      case SUBS1:       result = asm_arith_logic(instr, parm, 3);                        break;      case SUBU0:       result = asm_arith_logic(instr, parm, 3);                        break;      case SUBU1:       result = asm_arith_logic(instr, parm, 3);                        break;      case SUB0:        result = asm_arith_logic(instr, parm, 3);                        break;      case SUB1:        result = asm_arith_logic(instr, parm, 3);                        break;      case LOADSET0:    result = asm_load_store(instr, parm, 4);                        break;      case LOADSET1:    result = asm_load_store(instr, parm, 4);                        break;      case SUBCS0:      result = asm_arith_logic(instr, parm, 3);                        break;      case SUBCS1:      result = asm_arith_logic(instr, parm, 3);                        break;      case SUBCU0:      result = asm_arith_logic(instr, parm, 3);                        break;      case SUBCU1:      result = asm_arith_logic(instr, parm, 3);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -