+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+char *get_op(pCodeOp *pcop,char *buffer, size_t size)
+{
+ regs *r;
+ static char b[50];
+ char *s;
+ int use_buffer = 1; // copy the string to the passed buffer pointer
+
+ if(!buffer) {
+ buffer = b;
+ size = sizeof(b);
+ use_buffer = 0; // Don't bother copying the string to the buffer.
+ }
+
+ if(pcop) {
+ switch(pcop->type) {
+ case PO_INDF:
+ case PO_FSR:
+ if(use_buffer) {
+ SAFE_snprintf(&buffer,&size,"%s",PCOR(pcop)->r->name);
+ return buffer;
+ }
+ //return PCOR(pcop)->r->name;
+ return pcop->name;
+ break;
+ case PO_GPR_TEMP:
+ if (PCOR(pcop)->r->type == REG_STK)
+ r = typeRegWithIdx(PCOR(pcop)->r->rIdx,REG_STK,1);
+ else
+ r = pic14_regWithIdx(PCOR(pcop)->r->rIdx);
+
+ if(use_buffer) {
+ SAFE_snprintf(&buffer,&size,"%s",r->name);
+ return buffer;
+ }
+
+ return r->name;
+
+
+ case PO_IMMEDIATE:
+ s = buffer;
+ if(PCOI(pcop)->_const) {
+
+ if( PCOI(pcop)->offset >= 0 && PCOI(pcop)->offset<4) {
+ switch(PCOI(pcop)->offset) {
+ case 0:
+ SAFE_snprintf(&s,&size,"low (%s+%d)",pcop->name, PCOI(pcop)->index);
+ break;
+ case 1:
+ SAFE_snprintf(&s,&size,"high (%s+%d)",pcop->name, PCOI(pcop)->index);
+ break;
+ case 2:
+ SAFE_snprintf(&s,&size,"0x%02x",PCOI(pcop)->_const ? GPTRTAG_CODE : GPTRTAG_DATA);
+ break;
+ default:
+ fprintf (stderr, "PO_IMMEDIATE/_const/offset=%d\n", PCOI(pcop)->offset);
+ assert ( !"offset too large" );
+ SAFE_snprintf(&s,&size,"(((%s+%d) >> %d)&0xff)",
+ pcop->name,
+ PCOI(pcop)->index,
+ 8 * PCOI(pcop)->offset );
+ }
+ } else
+ SAFE_snprintf(&s,&size,"LOW (%s+%d)",pcop->name,PCOI(pcop)->index);
+ } else {
+ if( !PCOI(pcop)->offset) { // && PCOI(pcc->pcop)->offset<4)
+ SAFE_snprintf(&s,&size,"(%s + %d)",
+ pcop->name,
+ PCOI(pcop)->index);
+ } else {
+ switch(PCOI(pcop)->offset) {
+ case 0:
+ SAFE_snprintf(&s,&size,"(%s + %d)",pcop->name, PCOI(pcop)->index);
+ break;
+ case 1:
+ SAFE_snprintf(&s,&size,"high (%s + %d)",pcop->name, PCOI(pcop)->index);
+ break;
+ case 2:
+ SAFE_snprintf(&s,&size,"0x%02x",PCOI(pcop)->_const ? GPTRTAG_CODE : GPTRTAG_DATA);
+ break;
+ default:
+ fprintf (stderr, "PO_IMMEDIATE/mutable/offset=%d\n", PCOI(pcop)->offset);
+ assert ( !"offset too large" );
+ SAFE_snprintf(&s,&size,"((%s + %d) >> %d)&0xff",pcop->name, PCOI(pcop)->index, 8*PCOI(pcop)->offset);
+ break;
+ }
+ }
+ }
+
+ return buffer;
+
+ case PO_DIR:
+ s = buffer;
+ //size = sizeof(buffer);
+ if( PCOR(pcop)->instance) {
+ SAFE_snprintf(&s,&size,"(%s + %d)",
+ pcop->name,
+ PCOR(pcop)->instance );
+ //fprintf(stderr,"PO_DIR %s\n",buffer);
+ } else
+ SAFE_snprintf(&s,&size,"%s",pcop->name);
+ return buffer;
+
+ case PO_LABEL:
+ s = buffer;
+ if (pcop->name) {
+ if(PCOLAB(pcop)->offset == 1)
+ SAFE_snprintf(&s,&size,"HIGH(%s)",pcop->name);
+ else
+ SAFE_snprintf(&s,&size,"%s",pcop->name);
+ }
+ return buffer;
+
+ case PO_GPR_BIT:
+ if(PCOR(pcop)->r) {
+ if(use_buffer) {
+ SAFE_snprintf(&buffer,&size,"%s",PCOR(pcop)->r->name);
+ return buffer;
+ }
+ return PCOR(pcop)->r->name;
+ }
+
+ /* fall through to the default case */
+ default:
+ if(pcop->name) {
+ if(use_buffer) {
+ SAFE_snprintf(&buffer,&size,"%s",pcop->name);
+ return buffer;
+ }
+ return pcop->name;
+ }
+ }
+ }