Пример #1
0
void Vxls::allocate(Interval* current) {
  PhysReg::Map<unsigned> free_until; // 0 by default
  RegSet allow;
  unsigned conflict = constrain(current, allow);
  allow.forEach([&](PhysReg r) { free_until[r] = conflict; });
  for (auto ivl : active) {
    free_until[ivl->reg] = 0;
  }
  for (auto ivl : inactive) {
    auto until = current->nextIntersect(ivl);
    free_until[ivl->reg] = std::min(until, free_until[ivl->reg]);
  }
  auto r = find(free_until);
  auto pos = free_until[r];
  if (pos >= current->end()) {
    return assignReg(current, r);
  }
  if (pos > current->start()) {
    // r is free for the first part of current
    auto prev_use = current->lastUseBefore(pos);
    auto min_split = std::max(prev_use, current->start() + 1);
    auto max_split = pos;
    assert(min_split <= max_split);
    auto split_pos = std::max(min_split, max_split); // todo: find good spot
    split_pos = nearestSplitBefore(split_pos);
    if (split_pos > current->start()) {
      auto second = current->split(split_pos, true);
      pending.push(second);
      return assignReg(current, r);
    }
  }
  // must spill current or another victim
  allocBlocked(current);
}
Пример #2
0
/*always put first var at RSI,second var at RDI,please note the order of parameters for cmp instruction*/
void genCMP(uint32_t op)
{
	FreeReg(REG_RDI);
	assignReg(REG_RDI);
	FreeReg(REG_RSI);
	assignReg(REG_RSI);
	asmPrintf_func("    cmpq    %%rdi,%%rsi\n");
	FreeReg(REG_RDI);
	FreeReg(REG_RSI);

	operand_push(NULL, NOT_SPECIFIED);
	opTop->tk_code = op;
}
Пример #3
0
static void genADD_rax(uint32_t op, uint32_t mode)
{
	char instr[5];
	uint32_t reg;

	switch (op) {
	case tk_PLUS:
		strcpy(instr, "addq");
		break;
	case tk_MINUS:
		strcpy(instr, "subq");
		break;
	default:
		interERROR("ADD type instruction generating error!");
		break;
	}
	if (mode == RET_AT_TOP) {
		operand_pop();
	}
	reg = FindFreeReg();
	assignReg(reg);
	asmPrintf_func("    %s    %%%s, %%%s\n", instr, reg_pool[reg].reg_name, reg_pool[REG_RAX].reg_name);/*store to second reg*/

	if (mode == RET_AT_SECOND) {
		operand_pop();
	}

	setReg_Return(REG_RAX);
	setReg_Unused(reg);
	operand_push(&ret_sym, NOT_SPECIFIED);
}
Пример #4
0
void AnalogToDigitalConverter::begin(byte analogReference)
{
  assignReg(ADMUX,(1<<REFS0),analogReference);

  clearAndSetReg(ADCSRA,(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0),biggestBit(F_CPU/MAX_ADC_CLOCK)<<ADPS0);  // Set the fastest clock possible

  resume();
  sample(0);  // Throw away the first sample because its bad.
}
Пример #5
0
static void genMUL_rax(uint32_t op, uint32_t mode)
{
	char instr[6];
	uint32_t reg;

	if (mode == RET_AT_TOP) {
		operand_pop();
	}

	switch (op) {
	case tk_STAR:
		strcpy(instr, "imulq");
		reg = FindFreeReg();
		assignReg(reg);
		asmPrintf_func("    %s   %%%s, %%%s\n", instr, reg_pool[reg].reg_name, reg_pool[REG_RAX].reg_name);/*store to second reg*/
		if (mode == RET_AT_SECOND) {
			operand_pop();
		}
		setReg_Return(REG_RAX);
		setReg_Unused(reg);
		break;
	case tk_DIVIDE:
	case tk_MOD:
		strcpy(instr, "idivq");
		FreeReg(REG_RCX);
		assignReg(REG_RCX);
		FreeReg(REG_RAX);
		assignReg(REG_RAX);
		asmPrintf_func("    cqo\n");/*negative idiv : http://stackoverflow.com/questions/10343155/x86-assembly-handling-the-idiv-instruction*/
		asmPrintf_func("    %s   %%%s\n", instr, reg_pool[REG_RCX].reg_name); /*quotient:rax   ,  remainder:rdx*/
		if (op == tk_MOD) {
			instrMOV_REG_REG(BYTE_8, reg_pool[REG_RDX].reg_name, reg_pool[REG_RAX].reg_name);
		}
		setReg_Return(REG_RAX);
		setReg_Unused(REG_RDX);
		setReg_Unused(REG_RCX);
		break;
	default:
		interERROR("MUL type instruction generating error!");
		break;
	}
	operand_push(&ret_sym, NOT_SPECIFIED);

}
Пример #6
0
uint16_t AnalogToDigitalConverter::sample(byte channel)
{
  //while(getReg(ADCSRA,(1<<ADSC)));  // Wait for prior sample 
  clearAndSetReg(ADMUX,AnalogMuxMask,channel);
  assignReg(ADCSRA,(1<<ADSC),1);
  while(getReg(ADCSRA,(1<<ADSC)));  // Wait for prior sample
  uint16_t result = ADCL;
  result = result | (((uint16_t)(ADCH))<<8);
  return result;
}
Пример #7
0
// When all registers are in use, find a good interval to split and spill,
// which could be the current interval.  When an interval is split and the
// second part is spilled, possibly split the second part again before the
// next use-pos that requires a register, and enqueue the third part.
void Vxls::allocBlocked(Interval* current) {
  PhysReg::Map<unsigned> used, blocked;
  RegSet allow;
  unsigned conflict = constrain(current, allow); // repeated from allocate
  allow.forEach([&](PhysReg r) { used[r] = blocked[r] = conflict; });
  auto const cur_start = current->start();
  // compute next use of active registers, so we can pick the furthest one
  for (auto ivl : active) {
    if (ivl->fixed()) {
      blocked[ivl->reg] = used[ivl->reg] = 0;
    } else {
      auto use_pos = ivl->firstUseAfter(cur_start);
      used[ivl->reg] = std::min(use_pos, used[ivl->reg]);
    }
  }
  // compute next intersection/use of inactive regs to find whats free longest
  for (auto ivl : inactive) {
    auto intersect_pos = current->nextIntersect(ivl);
    if (intersect_pos == kMaxPos) continue;
    if (ivl->fixed()) {
      blocked[ivl->reg] = std::min(intersect_pos, blocked[ivl->reg]);
      used[ivl->reg] = std::min(blocked[ivl->reg], used[ivl->reg]);
    } else {
      auto use_pos = ivl->firstUseAfter(cur_start);
      used[ivl->reg] = std::min(use_pos, used[ivl->reg]);
    }
  }
  // choose the best victim register(s) to spill
  auto r = find(used);
  auto used_pos = used[r];
  if (used_pos < current->firstUse()) {
    // all other intervals are used before current's first register-use
    return spill(current);
  }
  auto block_pos = blocked[r];
  if (block_pos < current->end()) {
    auto prev_use = current->lastUseBefore(block_pos);
    auto min_split = std::max(prev_use, cur_start + 1);
    auto max_split = block_pos;
    assert(cur_start < min_split && min_split <= max_split);
    auto split_pos = std::max(min_split, max_split);
    split_pos = nearestSplitBefore(split_pos);
    if (split_pos > current->start()) {
      auto second = current->split(split_pos, true);
      pending.push(second);
    }
  }
  spillOthers(current, r);
  assignReg(current, r);
}
Пример #8
0
void Vxls::walkIntervals() {
  for (auto ivl : intervals) {
    if (!ivl) continue;
    if (ivl->fixed()) {
      assignReg(ivl, ivl->vreg);
    } else if (ivl->cns) {
      spill(ivl);
    } else {
      pending.push(ivl);
    }
  }
  while (!pending.empty()) {
    auto current = pending.top();
    pending.pop();
    update(current->start());
    allocate(current);
  }
}
Пример #9
0
void AnalogToDigitalConverter::resume()
{
  assignReg(ADCSRA,(1<<ADEN),1);  // turn on power
}
Пример #10
0
void AnalogToDigitalConverter::pause()
{
  assignReg(ADCSRA,(1<<ADEN),0);  // turn on power
}
Пример #11
0
void AnalogComparator::resume()
{
  assignReg(ACSR,(1<<ACIE) | (1<<ACD),1);  // Turn on the interrupt and power
}
Пример #12
0
void AnalogComparator::pause()
{
  assignReg(ACSR,(1<<ACIE) | (1<<ACD),0);  // Turn off the interrupt and power
}