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

📄 slang_assemble.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
			{
				assert (!"var->initializer, oper_identifier");
			}
			else
			{
				if (!reference)
				{
					if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,
						info->addr_tmp, 4))
						return 0;
				}
				/* XXX: globals! */
				if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, var->address,
					size))
					return 0;
				if (!reference)
				{
					if (!slang_assembly_file_push (file, slang_asm_addr_copy))
						return 0;
					if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
						return 0;
					if (!dereference (file, op, space, info))
						return 0;
				}
			}
		}
		break;
	case slang_oper_sequence:
		{
			slang_assembly_stack_info stk;
			if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
				return 0;
			/* TODO: pass-in stk to cleanup */
			if (!_slang_cleanup_stack (file, op->children, 0, space))
				return 0;
			if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info,
				&stk))
				return 0;
			/* TODO: inspect stk */
		}
		break;
	case slang_oper_assign:
		if (!_slang_assemble_assign (file, op, "=", reference, space, info))
			return 0;
		break;
	case slang_oper_addassign:
		if (!_slang_assemble_assign (file, op, "+=", reference, space, info))
			return 0;
		break;
	case slang_oper_subassign:
		if (!_slang_assemble_assign (file, op, "-=", reference, space, info))
			return 0;
		break;
	case slang_oper_mulassign:
		if (!_slang_assemble_assign (file, op, "*=", reference, space, info))
			return 0;
		break;
	/*case slang_oper_modassign:*/
	/*case slang_oper_lshassign:*/
	/*case slang_oper_rshassign:*/
	/*case slang_oper_orassign:*/
	/*case slang_oper_xorassign:*/
	/*case slang_oper_andassign:*/
	case slang_oper_divassign:
		if (!_slang_assemble_assign (file, op, "/=", reference, space, info))
			return 0;
		break;
	case slang_oper_select:
		if (!_slang_assemble_select (file, op, flow, space, info))
			return 0;
		break;
	case slang_oper_logicalor:
		if (!_slang_assemble_logicalor (file, op, flow, space, info))
			return 0;
		break;
	case slang_oper_logicaland:
		if (!_slang_assemble_logicaland (file, op, flow, space, info))
			return 0;
		break;
	case slang_oper_logicalxor:
		if (!call_function_name (file, "^^", op->children, 2, 0, space, info))
			return 0;
		break;
	/*case slang_oper_bitor:*/
	/*case slang_oper_bitxor:*/
	/*case slang_oper_bitand:*/
	case slang_oper_less:
		if (!call_function_name (file, "<", op->children, 2, 0, space, info))
			return 0;
		break;
	case slang_oper_greater:
		if (!call_function_name (file, ">", op->children, 2, 0, space, info))
			return 0;
		break;
	case slang_oper_lessequal:
		if (!call_function_name (file, "<=", op->children, 2, 0, space, info))
			return 0;
		break;
	case slang_oper_greaterequal:
		if (!call_function_name (file, ">=", op->children, 2, 0, space, info))
			return 0;
		break;
	/*case slang_oper_lshift:*/
	/*case slang_oper_rshift:*/
	case slang_oper_add:
		if (!call_function_name (file, "+", op->children, 2, 0, space, info))
			return 0;
		break;
	case slang_oper_subtract:
		if (!call_function_name (file, "-", op->children, 2, 0, space, info))
			return 0;
		break;
	case slang_oper_multiply:
		if (!call_function_name (file, "*", op->children, 2, 0, space, info))
			return 0;
		break;
	/*case slang_oper_modulus:*/
	case slang_oper_divide:
		if (!call_function_name (file, "/", op->children, 2, 0, space, info))
			return 0;
		break;
	case slang_oper_equal:
		{
			slang_assembly_stack_info stk;
			if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
				return 0;
			/* TODO: inspect stk */
			if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
				return 0;
			/* TODO: inspect stk */
			if (!equality (file, op->children, space, info, 1))
				return 0;
		}
		break;
	case slang_oper_notequal:
		{
			slang_assembly_stack_info stk;
			if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
				return 0;
			/* TODO: inspect stk */
			if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
				return 0;
			/* TODO: inspect stk */
			if (!equality (file, op->children, space, info, 0))
				return 0;
		}
		break;
	case slang_oper_preincrement:
		if (!_slang_assemble_assign (file, op, "++", reference, space, info))
			return 0;
		break;
	case slang_oper_predecrement:
		if (!_slang_assemble_assign (file, op, "--", reference, space, info))
			return 0;
		break;
	case slang_oper_plus:
		if (!call_function_name (file, "+", op->children, 1, 0, space, info))
			return 0;
		break;
	case slang_oper_minus:
		if (!call_function_name (file, "-", op->children, 1, 0, space, info))
			return 0;
		break;
	/*case slang_oper_complement:*/
	case slang_oper_not:
		if (!call_function_name (file, "!", op->children, 1, 0, space, info))
			return 0;
		break;
	case slang_oper_subscript:
		{
			slang_assembly_stack_info _stk;
			slang_assembly_typeinfo ti_arr, ti_elem;
			unsigned int arr_size = 0, elem_size = 0;
			if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,
				&_stk))
				return 0;
			if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &_stk))
				return 0;
			slang_assembly_typeinfo_construct (&ti_arr);
			if (!_slang_typeof_operation (op->children, space, &ti_arr))
			{
				slang_assembly_typeinfo_destruct (&ti_arr);
				return 0;
			}
			if (!sizeof_variable (&ti_arr.spec, slang_qual_none, NULL, space, &arr_size))
			{
				slang_assembly_typeinfo_destruct (&ti_arr);
				return 0;
			}
			slang_assembly_typeinfo_construct (&ti_elem);
			if (!_slang_typeof_operation (op, space, &ti_elem))
			{
				slang_assembly_typeinfo_destruct (&ti_arr);
				slang_assembly_typeinfo_destruct (&ti_elem);
				return 0;
			}
			if (!sizeof_variable (&ti_elem.spec, slang_qual_none, NULL, space, &elem_size))
			{
				slang_assembly_typeinfo_destruct (&ti_arr);
				slang_assembly_typeinfo_destruct (&ti_elem);
				return 0;
			}
			if (!slang_assembly_file_push (file, slang_asm_int_to_addr))
			{
				slang_assembly_typeinfo_destruct (&ti_arr);
				slang_assembly_typeinfo_destruct (&ti_elem);
				return 0;
			}
			if (!slang_assembly_file_push_label (file, slang_asm_addr_push, elem_size))
			{
				slang_assembly_typeinfo_destruct (&ti_arr);
				slang_assembly_typeinfo_destruct (&ti_elem);
				return 0;
			}
			if (!slang_assembly_file_push (file, slang_asm_addr_multiply))
			{
				slang_assembly_typeinfo_destruct (&ti_arr);
				slang_assembly_typeinfo_destruct (&ti_elem);
				return 0;
			}
			if (reference)
			{
				if (!slang_assembly_file_push (file, slang_asm_addr_add))
				{
					slang_assembly_typeinfo_destruct (&ti_arr);
					slang_assembly_typeinfo_destruct (&ti_elem);
					return 0;
				}
			}
			else
			{
				unsigned int i;
				for (i = 0; i < elem_size; i += 4)
				{
					if (!slang_assembly_file_push_label2 (file, slang_asm_float_move,
						arr_size - elem_size + i + 4, i + 4))
					{
						slang_assembly_typeinfo_destruct (&ti_arr);
						slang_assembly_typeinfo_destruct (&ti_elem);
						return 0;
					}
				}
				if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
				{
					slang_assembly_typeinfo_destruct (&ti_arr);
					slang_assembly_typeinfo_destruct (&ti_elem);
					return 0;
				}
				if (!slang_assembly_file_push_label (file, slang_asm_local_free,
					arr_size - elem_size))
				{
					slang_assembly_typeinfo_destruct (&ti_arr);
					slang_assembly_typeinfo_destruct (&ti_elem);
					return 0;
				}
			}
			slang_assembly_typeinfo_destruct (&ti_arr);
			slang_assembly_typeinfo_destruct (&ti_elem);
		}
		break;
	case slang_oper_call:
		{
			slang_function *fun = _slang_locate_function (op->identifier, op->children,
				op->num_children, space);
			if (fun == NULL)
			{
				if (!_slang_assemble_constructor (file, op, flow, space, info))
					return 0;
			}
			else
			{
				if (!call_function (file, fun, op->children, op->num_children, 0, space, info))
					return 0;
			}
		}
		break;
	case slang_oper_field:
		{
			slang_assembly_typeinfo ti_after, ti_before;
			slang_assembly_stack_info _stk;
			slang_assembly_typeinfo_construct (&ti_after);
			if (!_slang_typeof_operation (op, space, &ti_after))
			{
				slang_assembly_typeinfo_destruct (&ti_after);
				return 0;
			}
			slang_assembly_typeinfo_construct (&ti_before);
			if (!_slang_typeof_operation (op->children, space, &ti_before))
			{
				slang_assembly_typeinfo_destruct (&ti_after);
				slang_assembly_typeinfo_destruct (&ti_before);
				return 0;
			}
			if (!reference && ti_after.is_swizzled)
			{
				if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,
					info->swizzle_tmp, 16))
				{
					slang_assembly_typeinfo_destruct (&ti_after);
					slang_assembly_typeinfo_destruct (&ti_before);
					return 0;
				}
			}
			if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,
				&_stk))
			{
				slang_assembly_typeinfo_destruct (&ti_after);
				slang_assembly_typeinfo_destruct (&ti_before);
				return 0;
			}
			/* TODO: inspect stk */
			if (ti_after.is_swizzled)
			{
				if (reference)
				{
					if (ti_after.swz.num_components == 1)
					{
						if (!slang_assembly_file_push_label (file, slang_asm_addr_push,
							ti_after.swz.swizzle[0] * 4))
						{
							slang_assembly_typeinfo_destruct (&ti_after);
							slang_assembly_typeinfo_destruct (&ti_before);
							return 0;
						}
						if (!slang_assembly_file_push (file, slang_asm_addr_add))
						{
							slang_assembly_typeinfo_destruct (&ti_after);
							slang_assembly_typeinfo_destruct (&ti_before);
							return 0;
						}
					}
					else
					{
						unsigned int i;
						for (i = 0; i < ti_after.swz.num_components; i++)
							stk->swizzle_mask |= 1 << ti_after.swz.swizzle[i];
					}
				}
				else
				{
					if (!_slang_assemble_constructor_from_swizzle (file, &ti_after.swz,
						&ti_after.spec, &ti_before.spec, info))
					{
						slang_assembly_typeinfo_destruct (&ti_after);
						slang_assembly_typeinfo_destruct (&ti_before);
						return 0;
					}
				}
			}
			else
			{
				if (reference)
				{
					/* TODO: struct field address */
				}
				else
				{
					/* TODO: struct field value */
				}
			}
			slang_assembly_typeinfo_destruct (&ti_after);
			slang_assembly_typeinfo_destruct (&ti_before);
		}
		break;
	case slang_oper_postincrement:
		if (!call_function_name_dummyint (file, "++", op->children, space, info))
			return 0;
		if (!dereference (file, op, space, info))
			return 0;
		break;
	case slang_oper_postdecrement:
		if (!call_function_name_dummyint (file, "--", op->children, space, info))
			return 0;
		if (!dereference (file, op, space, info))
			return 0;
		break;
	default:
		return 0;
	}
	return 1;
}









void xxx_first (slang_assembly_file *file)
{
	slang_assembly_file_push (file, slang_asm_jump);
}

void xxx_prolog (slang_assembly_file *file, unsigned int addr)
{
	file->code[0].param[0] = file->count;
	slang_assembly_file_push_label (file, slang_asm_call, addr);
	slang_assembly_file_push (file, slang_asm_exit);
}

⌨️ 快捷键说明

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