Пример #1
0
void genword(char * buffer, int begin, int size, int curcar, char result[SIZE+1]) {
	int i = 0;
	char tmp1, tmp2, tmp3;

	if (size == 1) {
		assert(curcar < NBCAR && curcar >= 0);
		buffer[begin] = C[curcar];
		/*printf("%s\n", buffer);*/
		tmp1 = buffer[0], tmp2 = buffer[1], tmp3 = buffer[2];
		if (decode(result, buffer) == 1) {
			printf("%s:%s\n\n", buffer, result);
		}
		assert(tmp1 == buffer[0] && tmp2 == buffer[1] && tmp3 == buffer[2]);

		if (curcar >= NBCAR -1) {
			return;
		}
		genword(buffer, begin, size, curcar+1, result);
	}

	else {
		for (i = 0; i < NBCAR; i++) {
			buffer[begin] = C[i];
			genword(buffer, begin+1, size-1, 0, result);
		}
	}
}
Пример #2
0
int main(void) {
	//printf("%d\n", XOR(65, 42));
	//printf("%d\n", XOR(107, 42));

	char buffer[4] = {0, 0, 0, 0}, result[SIZE+1] = "";

	genword(buffer, 0, 3, 0, result);

	return 0;
}
Пример #3
0
void dumplits(void)
/*
 *      dump the string literal pool.
 */
{
        while( strtab != 0) {
                cseg();
                nl();
                put_label(strtab->label);
								genstring(strtab->str,strtab->type);
								if (strtab->type)
									genword(0);
								else
									genbyte(0);
                strtab = strtab->next;
                }
        nl();
}
Пример #4
0
int genstring(char *str, int uselong)
/*
 * Generate a string literal
 */
{
	if (uselong) {
		while  (*(short *)str) {
			genword(*((short *)str));
			str+=2;
		}
		return pstrlen(str)*2;
	}
	else {
		while (*str)
			genbyte(*str++);
		return strlen(str);
	}
}
Пример #5
0
void gcode(void) {
  int i, n, t, r, stacksize, addr, pc, disp, rel, errs, more, func_start;
  Branch *b, *bn;

  // Generate function prolog
  func_start = cur_text_section->data_offset;
  if (!func_naked) {
    // Align local size to word
    stacksize = (-loc + 3) & -4;

    if (stacksize >= 4096) {
      // Generate stack guard since parameters can cross page boundary
      Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
      gen(0xb8); // mov stacksize, %eax
      genword(stacksize);
      gen(0xe8);  // call __chkstk, (does the stackframe too)
      put_reloc(cur_text_section, sym, cur_text_section->data_offset, R_386_PC32);
      genword(-4);
    } else {
      if (do_debug || loc || !func_noargs) {
        gen(0x55); // push %ebp
        gen(0x89); // mov %esp, %ebp
        gen(0xe5);
      }
      if (stacksize > 0) {
        if (stacksize == (char) stacksize) {
          gen(0x83);  // sub esp, stacksize
          gen(0xec);
          gen(stacksize);
        } else {
          gen(0x81);  // sub esp, stacksize
          gen(0xec);
          genword(stacksize);
        }
      }
    }
    
    // Save callee-saved registers used by function.
    for (r = 0; r < NB_REGS; ++r) {
      if ((reg_classes[r] & RC_SAVE) && (regs_used & (1 << r))) {
        gen(0x50 + r); // push r
      }
    }
  }

  // Optimize jumps
  more = 1;
  while (more) {
    more = 0;

    for (i = 0; i < br; ++i) {
      b = branch + i;
      if (b->type == CodeLabel) b->target = 0;
      if (b->type != CodeJump) continue;

      t = skip_nops(b->target, 1);
      if (branch[t].type == CodeJump && !branch[t].param && b->target != branch[t].target) {
        // Eliminate jump to jump
        b->target = branch[t].target;
        more = 1;
        continue;
      }

      // Find next non-nop
      n = i + 1;
      while (branch[n].type == CodeNop || branch[n].type == CodeLine) n++;
      bn = branch + n;
      if (b->ind != bn->ind) continue;

      if (!b->param && bn->type == CodeJump) {
        // Eliminate dead jump instruction
        bn->type = CodeNop;
        more = 1;
        continue;
      }

      if (b->target > i && b->target <= n) {
        // Eliminate jump to next instruction
        b->type = CodeNop;
        more = 1;
        continue;
      }
      
      t = skip_nops(n + 1, 0);
      if (bn->type == CodeJump && !bn->param && b->target == t && bn->ind == branch[t].ind) {
        // Optimize inverted jump
        if (b->param) b->param ^= 1;
        b->target = bn->target;
        bn->type = CodeNop;
        more = 1;
        continue;
      }
    }

    // Eliminate unused labels
    for (i = 0; i < br; ++i) {
      b = branch + i;
      if (b->type == CodeJump) branch[b->target].target++;
    }
    for (i = 0; i < br; ++i) {
      b = branch + i;
      if (b->type == CodeLabel && !b->target && !b->sym) {
        // Remove label with no references
        b->type = CodeNop;
        more = 1;
      }
    }
  }

  // Assign addresses to branch points, assuming only long jumps
  addr = cur_text_section->data_offset;
  pc = 0;
  for (i = 0; i < br; ++i) {
    b = branch + i;
    addr += b->ind - pc;
    b->addr = addr;
    switch (b->type) {
      case CodeJump:
        addr += 5;
        if (b->param != 0) addr++;
        break;
        
      case CodeAlign:
        // Use convervative estimate for short/long jump estimation
        addr += b->param - 1;
        break;
    }
    pc = b->ind;
  }
  
  // Find jumps which can be encoded as short jumps
  for (i = 0; i < br; ++i) {
    b = branch + i;
    if (b->type == CodeJump) {
      disp = branch[b->target].addr - b->addr - 2;
      if (b->param) disp--;
      if (disp == (char) disp) b->type = CodeShortJump;
    }
  }

  // Assign final addresses to branch points
  addr = cur_text_section->data_offset;
  pc = 0;
  for (i = 0; i < br; ++i) {
    b = branch + i;
    addr += b->ind - pc;
    b->addr = addr;
    switch (b->type) {
      case CodeJump:
        addr += 5;
        if (b->param) addr++;
        break;

      case CodeShortJump:
        addr += 2;
        break;
      
      case CodeAlign:
        addr = (addr + b->param - 1) & -b->param;
        break;
    }
    pc = b->ind;
  }

  // Generate code blocks
  pc = 0;
  errs = 0;
  for (i = 0; i < br; ++i) {
    b = branch + i;
    
    // Output code block before branch point
    if (b->ind != pc) {
      genblk(code + pc, b->ind - pc);
      pc = b->ind;
    }

    switch (b->type) {
      case CodeLabel:
        // Export label if symbol defined
        if (b->sym) {
          put_extern_sym_ex(b->sym, cur_text_section, b->addr, 0, 0);
          sym_free(b->sym);
        }
        break;

      case CodeJump:
        // Generate long jump instruction
        if (branch[b->target].type != CodeLabel) {
          printf("internal error: jump %d to non-label %d\n", i, b->target);
          errs++;
        }
        if (b->param > 0xff) error("invalid displacement");
        if (b->param == 0) {
          gen(0xe9);
          genword(branch[b->target].addr - (b->addr + 5));
        } else {
          gen(0x0f);
          gen(b->param - 0x10);
          genword(branch[b->target].addr - (b->addr + 6));
        }
        break;

      case CodeShortJump:
        // Generate short jump instruction
        if (branch[b->target].type != CodeLabel) {
          printf("internal error: jump %d to non-label %d\n", i, b->target);
          errs++;
        }
        if (b->param == 0) {
          gen(0xeb);
        } else {
          gen(b->param - 0x20);
        }
        gen(branch[b->target].addr - (b->addr + 2));
        break;

      case CodeReloc:
        if (b->param) {
          rel = R_386_PC32;
        } else {
          rel = R_386_32;
        }
        put_elf_reloc(symtab_section, cur_text_section, b->addr, rel, b->target);
        break;
        
      case CodeAlign:
        i = addr;
        while (i & (b->param - 1)) {
          gen(b->target);
          i++;
        }
        break;

      case CodeLine:
        put_stabn(N_SLINE, 0, b->target, b->addr - func_start);
        break;
    }
  }

  // Generate function epilog
  if (!func_naked) {
    // Restore callee-saved registers used by function.
    for (r = NB_REGS; r >= 0; --r) {
      if ((reg_classes[r] & RC_SAVE) && (regs_used & (1 << r))) {
        gen(0x58 + r); // pop r
      }
    }

    if (do_debug || loc || !func_noargs) gen(0xc9); // leave

    // Generate return
    if (func_ret_sub == 0) {
      gen(0xc3); // ret
    } else {
      gen(0xc2); // ret n
      gen(func_ret_sub);
      gen(func_ret_sub >> 8);
    }
  }

#ifdef DEBUG_BRANCH
  printf("\nbranch table for %s\n", func_name);
  printf(" #   t targ parm    ind      addr\n");
  printf("---- - ---- ----- -------- --------\n");
  for (i = 0; i < br; ++i) {
    b = branch + i;
    printf("%04d %c %04d %04x %08x %08x", i, "SLJjRANlE"[b->type], b->target, b->param, b->ind, b->addr);
    if (branch[i].sym) {
      printf(" sym=%s", get_tok_str(b->sym->v, NULL));
    }
    printf("\n");
  }
  printf("\n");
#endif

  if (errs) error("internal error: code generation");
}