Exemple #1
0
void cgLdContResumeAddr(IRLS& env, const IRInstruction* inst) {
  auto const dst = dstLoc(env, inst, 0).reg();
  auto const cont = srcLoc(env, inst, 0).reg();
  auto const isAsync = inst->extra<IsAsyncData>()->isAsync;
  auto const addrOff = BaseGenerator::resumeAddrOff() - genOffset(isAsync);
  vmain(env) << load{cont[addrOff], dst};
}
Exemple #2
0
void cgContPreNext(IRLS& env, const IRInstruction* inst) {
  auto const cont = srcLoc(env, inst, 0).reg();
  auto const checkStarted = inst->src(1)->boolVal();
  auto const isAsync = inst->extra<IsAsyncData>()->isAsync;
  auto& v = vmain(env);

  auto const sf = v.makeReg();

  // These asserts make sure that the startedCheck work.
  static_assert(uint8_t(BaseGenerator::State::Created) == 0, "used below");
  static_assert(uint8_t(BaseGenerator::State::Started) == 1, "used below");
  static_assert(uint8_t(BaseGenerator::State::Done) > 3, "");

  // These asserts ensure that the state transition works.  If we're in the
  // Created state we want to transition to Priming, and if we're in the
  // Started state we want to transition to Running.  By laying out the enum
  // this way we can avoid the branch and just transition by adding 2 to the
  // current state.
  static_assert(uint8_t(BaseGenerator::State::Priming) ==
                uint8_t(BaseGenerator::State::Created) + 2, "used below");
  static_assert(uint8_t(BaseGenerator::State::Running) ==
                uint8_t(BaseGenerator::State::Started) + 2, "used below");

  // Take exit if state != 1 (checkStarted) or if state > 1 (!checkStarted).
  auto stateOff = BaseGenerator::stateOff() - genOffset(isAsync);
  v << cmpbim{int8_t(BaseGenerator::State::Started), cont[stateOff], sf};
  fwdJcc(v, env, checkStarted ? CC_NE : CC_A, sf, inst->taken());

  // Transition the generator into either the Priming state (if we were just
  // created) or the Running state (if we were started).  Due to the way the
  // enum is layed out, we can model this by just adding 2.
  v << addlim{int8_t(2), cont[stateOff], v.makeReg()};
}
Exemple #3
0
void cgContValid(IRLS& env, const IRInstruction* inst) {
  auto const dst = dstLoc(env, inst, 0).reg();
  auto const cont = srcLoc(env, inst, 0).reg();
  auto const isAsync = inst->extra<IsAsyncData>()->isAsync;
  auto& v = vmain(env);

  // Return true if generator state is not Done.
  auto const sf = v.makeReg();
  auto const stateOff = BaseGenerator::stateOff() - genOffset(isAsync);
  v << cmpbim{int8_t(BaseGenerator::State::Done), cont[stateOff], sf};
  v << setcc{CC_NE, sf, dst};
}
Exemple #4
0
void cgContStarted(IRLS& env, const IRInstruction* inst) {
  auto const dst = dstLoc(env, inst, 0).reg();
  auto const cont = srcLoc(env, inst, 0).reg();
  auto& v = vmain(env);

  // Return true if generator state is not in the Created state.
  auto const sf = v.makeReg();
  auto const stateOff = BaseGenerator::stateOff() -
                        genOffset(false /* isAsync */);
  v << cmpbim{int8_t(BaseGenerator::State::Created), cont[stateOff], sf};
  v << setcc{CC_NE, sf, dst};
}
Exemple #5
0
void cgContStartedCheck(IRLS& env, const IRInstruction* inst) {
  auto const cont = srcLoc(env, inst, 0).reg();
  auto const isAsync = inst->extra<IsAsyncData>()->isAsync;
  auto& v = vmain(env);

  static_assert(uint8_t(BaseGenerator::State::Created) == 0, "used below");

  // Take exit if state == 0.
  auto const sf = v.makeReg();
  auto const stateOff = BaseGenerator::stateOff() - genOffset(isAsync);
  v << testbim{int8_t(0xffu), cont[stateOff], sf};
  v << jcc{CC_Z, sf, {label(env, inst->next()), label(env, inst->taken())}};
}
Exemple #6
0
/*Writes coresponing code to file, or throws appropriate error */
void processOpcode( int code, int * steer, char * pArg1, char * pArg2, char * pArg3, char * pArg4)
{
	int output = 0;
	int DR = -1;
	int SR = -1;
	int SR1 = -1;
	int SR2 = -1;
	int BR = -1;
	int num = -1;
	Symbol* temp = NULL;
	if(code <= 15 && code >= 0)
		output = code<<12;
	switch (code)
	{
	case 0:  /* BR if steering is 1-7 and NOP if 0 */
		if(*pArg2 != '\0' || *pArg3 != '\0' || *pArg4 !='\0'){
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);	
		}
		if(*steer==0 && *pArg1 != '\0') {
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);
		}
		
		
		if(*steer != 0) {
			/* br with nzp bits specified by steering */
			output += *steer<<9;
			temp = searchSymbol(pArg1);
			if(temp == NULL)	/*Label not found in symbol tabel */
			{
				printf("Error: Unidentified Label\n");
				closeFiles();
				exit(1);
			}
			num = genOffset(temp->location,9);	/*genOffset will throw out of bounds error if necisarry */
			output += (num&511);
		}	
		
		break;
	case 1:		/*ADD */
		DR = RegNum(pArg1);
		SR1 = RegNum(pArg2);
		/*Too many arguments, or invalid */
		if(*pArg4 != '\0'||SR1 == -1 || DR == -1)	
		{
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);
		}
		output += (DR<<9)+(SR1<<6);	/*Common to all implementations */		
		SR2=RegNum(pArg3);
		if(SR2 == -1)		/*Immediate Value */
		{
			num = toNum(pArg3);
			if(num>15 || num < -16)	/*5 Bits */
			{
				printf("Error: Immediate Value Out of Bounds\n");
				closeFiles();
				exit(3);
			}
			output+= (1<<5) + (num&31);
		}
		else	/*Register value */
		{
			output+=SR2;
		}
		
		break;
	case 2: /*LDB*/
		DR = RegNum(pArg1);
		BR = RegNum(pArg2);
		if(*pArg4 != '\0'|| BR == -1 || DR == -1)	
		{
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);
		}
		output += (DR<<9)+(BR<<6);	
		num = toNum(pArg3);
		if(num>31 || num < -32)	/* 6 Bits */
		{
			printf("Error: Immediate Value Out of Bounds\n");
			closeFiles();
			exit(3);
		}
		output += (num&63);
		break;
	case 3: /*STB*/
		SR = RegNum(pArg1);
		BR = RegNum(pArg2);
		if(*pArg4 != '\0'|| BR == -1 || SR == -1)	
		{
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);
		}
		output += (SR<<9)+(BR<<6);	
		num = toNum(pArg3);
		if(num>31 || num < -32)	/* 6 Bits */
		{
			printf("Error: Immediate Value Out of Bounds\n");
			closeFiles();
			exit(3);
		}
		output += (num&63);
		break;
	case 4: /* JSR & JSRR */
		if(*pArg2 != '\0' ||  *pArg3 != '\0' || *pArg4 != '\0')	
		{
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);
		}
		output += *steer << 11;
		if(*steer == 1) {
			/* JSR */
			temp = searchSymbol(pArg1);
			if(temp == NULL) {
				/*Label not found in symbol tabel */
				printf("Error: Unidentified Label\n");
				closeFiles();
				exit(1);
			}
			num = genOffset(temp->location,11);	/*genOffset will throw out of bounds error if necisarry */
			output += (num&2047);
		} else {
			/* JSRR */
			BR = RegNum(pArg1);
			output += BR<<6;
		}
		break;
	case 5:	/*AND */
		DR = RegNum(pArg1);
		SR1 = RegNum(pArg2);
		/*Too many arguments, or invalid */
		if(*pArg4 != '\0'||SR1 == -1 || DR == -1)	
		{
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);
		}
		output += (DR<<9)+(SR1<<6);	/*Common to all implementations */		
		SR2=RegNum(pArg3);
		if(SR2 == -1)		/*Immediate Value */
		{
			num = toNum(pArg3);
			if(num>15 || num < -16)	/*5 Bits */
			{
				printf("Error: Immediate Value Out of Bounds\n");
				closeFiles();
				exit(3);
			}
			output+= (1<<5) + (num & 31);
		}
		else	/*Register value */
		{
			output+=SR2;
		}
		
		break;
	case 6: /*LDW*/
		DR = RegNum(pArg1);
		BR = RegNum(pArg2);
		if(*pArg4 != '\0'|| BR == -1 || DR == -1)	
		{
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);
		}
		output += (DR<<9)+(BR<<6);	
		num = toNum(pArg3);
		if(num>31 || num < -32)	/* 6 Bits */
		{
			printf("Error: Immediate Value Out of Bounds\n");
			closeFiles();
			exit(3);
		}
		output += (num&63);
		break;
	case 7: /*STW*/
		SR = RegNum(pArg1);
		BR = RegNum(pArg2);
		if(*pArg4 != '\0'|| BR == -1 || SR == -1)	
		{
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);
		}
		output += (SR<<9)+(BR<<6);	
		num = toNum(pArg3);
		if(num>31 || num < -32)	/* 6 Bits */
		{
			printf("Error: Immediate Value Out of Bounds\n");
			closeFiles();
			exit(3);
		}
		output += (num&63);
		break;
	case 8:
		/* RTI */
		/* do nothing: bits 11-0 all 0 */	
		break;
	case 9:			/*XOR and NOT */
		DR = RegNum(pArg1);
		SR1 = RegNum(pArg2);
		/*Too many arguments, or invalid */
		if(*pArg4 != '\0'||SR1 == -1 || DR == -1)	
		{
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);
		}
		output += (DR<<9)+(SR1<<6);	/*Common to all implementations */
		if(*steer == 0)		/*XOR*/
		{
			SR2=RegNum(pArg3);
			if(SR2 == -1)		/*Immediate Value */
			{
				num = toNum(pArg3);
				if(num>15 || num < -16)	/*5 Bits */
				{
					printf("Error: Immediate Value Out of Bounds\n");
					closeFiles();
					exit(3);
				}
				output+= (1<<5) + (num&31);
			}
			else	/*Register value */
			{
				output+=SR2;
			}
		}
		else	/*NOT function */
		{
			if(*pArg3 != '\0')
			{
				printf("Error: invalid argument\n");
				closeFiles();
				exit(4);
			}
			output += 63;
		}
		break;
	/*Opcodes 10 and 11 are invalid */
	case 12:	/*JMP */
		if(*pArg2 != '\0' ||*pArg3 != '\0' || *pArg4 != '\0')
		{
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);
		}
		if(*steer == 0)
		{
			SR1 = RegNum(pArg1);
			if(SR1==-1)	/*Must be valid register  */
			{
				printf("Error: invalid argument\n");
				closeFiles();
				exit(4);
			}
			output+=SR1<<6;
		}
		else	/*RET */
		{
			if(*pArg1 != '\0')	/*Should not have anything here */
			{ 
				printf("Error: invalid argument\n");
				closeFiles();
				exit(4);
			}
			output+=7<<6;
		}
		break;
	case 13:	/*Shift */
		DR = RegNum(pArg1);
		SR1 = RegNum(pArg2);
		num = toNum(pArg3);
		if(*pArg4 != '\0' || DR==-1||SR1==-1)
		{
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);
		}
		if(num>15||num<0)
		{
			printf("Error: Immediate Value Out of Bounds\n");
			closeFiles();
			exit(3);
		}
		/*Steering integer also acts as steering bits */
		output += (DR<<9)+(SR1<<6)+((*steer)<<4)+num;
		break;
	case 14:	/*LEA */
		DR = RegNum(pArg1);
		temp = searchSymbol(pArg2);
		if(temp == NULL)	/*Label not found in symbol tabel */
		{
			printf("Error: Unidentified Label\n");
			closeFiles();
			exit(1);
		}
		if(DR==-1 || *pArg3 != '\0' || *pArg4 != '\0')
		{
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);
		}
		num = genOffset(temp->location,9);	/*genOffset will throw out of bounds error if necisarry */
		output+=(DR<<9)+(num&511);
		break;
	case 15:	/*TRAP */
		/*Must be hex */
		if(*pArg2 != '\0' || *pArg3 != '\0' || *pArg4 != '\0')
		{
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);
		}
		if(*steer == 1)	/*HALT */
		{
			if(*pArg1 != '\0')
			{
				printf("Error: invalid argument\n");
				closeFiles();
				exit(4);
			}
			num= 37;
		}
		else
		{
			if(*pArg1 != 'x')	/*Must be a hex value */
			{
				printf("Error: TRAP must be a hex value\n");
				closeFiles();
				exit(3);
			}
			num = toNum(pArg1);
			if(num>255||num<0)		/*>0 and no more than 8 digits */
			{
				printf("Error: TRAP Value Out of Bounds\n");
				closeFiles();
				exit(3);
			}
		}
		output+=num;
		break;
	case 16:	/*.FILL */
		if(*pArg2 != '\0' || *pArg3 != '\0' || *pArg4 != '\0')
		{
			printf("Error: invalid argument\n");
			closeFiles();
			exit(4);
		}
		num = toNum(pArg1);
		if(num>65535|| num< -32768)	/*Can be signed or unsigned */
		{
			printf("Error: TRAP Value Out of Bounds\n");
			closeFiles();
			exit(3);
		}
		output = num;
		break;
	default:
		printf("Error: invalid opcode\n");
		closeFiles();
		exit(2);
	}
	fprintf( outfile, "0x%0.4X\n", output );		/*Prints out formated Hex version of code */
}