1433d6423SLionel Sambuc /******************************************************************************
2433d6423SLionel Sambuc *
3433d6423SLionel Sambuc * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
4433d6423SLionel Sambuc *
5433d6423SLionel Sambuc *****************************************************************************/
6433d6423SLionel Sambuc
7*29492bb7SDavid van Moolenbroek /*
8*29492bb7SDavid van Moolenbroek * Copyright (C) 2000 - 2014, Intel Corp.
9433d6423SLionel Sambuc * All rights reserved.
10433d6423SLionel Sambuc *
11*29492bb7SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
12*29492bb7SDavid van Moolenbroek * modification, are permitted provided that the following conditions
13*29492bb7SDavid van Moolenbroek * are met:
14*29492bb7SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
15*29492bb7SDavid van Moolenbroek * notice, this list of conditions, and the following disclaimer,
16*29492bb7SDavid van Moolenbroek * without modification.
17*29492bb7SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*29492bb7SDavid van Moolenbroek * substantially similar to the "NO WARRANTY" disclaimer below
19*29492bb7SDavid van Moolenbroek * ("Disclaimer") and any redistribution must be conditioned upon
20*29492bb7SDavid van Moolenbroek * including a substantially similar Disclaimer requirement for further
21*29492bb7SDavid van Moolenbroek * binary redistribution.
22*29492bb7SDavid van Moolenbroek * 3. Neither the names of the above-listed copyright holders nor the names
23*29492bb7SDavid van Moolenbroek * of any contributors may be used to endorse or promote products derived
24*29492bb7SDavid van Moolenbroek * from this software without specific prior written permission.
25433d6423SLionel Sambuc *
26*29492bb7SDavid van Moolenbroek * Alternatively, this software may be distributed under the terms of the
27*29492bb7SDavid van Moolenbroek * GNU General Public License ("GPL") version 2 as published by the Free
28*29492bb7SDavid van Moolenbroek * Software Foundation.
29433d6423SLionel Sambuc *
30*29492bb7SDavid van Moolenbroek * NO WARRANTY
31*29492bb7SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*29492bb7SDavid van Moolenbroek * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*29492bb7SDavid van Moolenbroek * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*29492bb7SDavid van Moolenbroek * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*29492bb7SDavid van Moolenbroek * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*29492bb7SDavid van Moolenbroek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*29492bb7SDavid van Moolenbroek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*29492bb7SDavid van Moolenbroek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*29492bb7SDavid van Moolenbroek * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*29492bb7SDavid van Moolenbroek * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*29492bb7SDavid van Moolenbroek * POSSIBILITY OF SUCH DAMAGES.
42*29492bb7SDavid van Moolenbroek */
43433d6423SLionel Sambuc
44433d6423SLionel Sambuc #include "acpi.h"
45433d6423SLionel Sambuc #include "accommon.h"
46433d6423SLionel Sambuc #include "acinterp.h"
47433d6423SLionel Sambuc #include "amlcode.h"
48433d6423SLionel Sambuc #include "amlresrc.h"
49433d6423SLionel Sambuc
50433d6423SLionel Sambuc
51433d6423SLionel Sambuc #define _COMPONENT ACPI_EXECUTER
52433d6423SLionel Sambuc ACPI_MODULE_NAME ("exmisc")
53433d6423SLionel Sambuc
54433d6423SLionel Sambuc
55433d6423SLionel Sambuc /*******************************************************************************
56433d6423SLionel Sambuc *
57433d6423SLionel Sambuc * FUNCTION: AcpiExGetObjectReference
58433d6423SLionel Sambuc *
59433d6423SLionel Sambuc * PARAMETERS: ObjDesc - Create a reference to this object
60433d6423SLionel Sambuc * ReturnDesc - Where to store the reference
61433d6423SLionel Sambuc * WalkState - Current state
62433d6423SLionel Sambuc *
63433d6423SLionel Sambuc * RETURN: Status
64433d6423SLionel Sambuc *
65433d6423SLionel Sambuc * DESCRIPTION: Obtain and return a "reference" to the target object
66433d6423SLionel Sambuc * Common code for the RefOfOp and the CondRefOfOp.
67433d6423SLionel Sambuc *
68433d6423SLionel Sambuc ******************************************************************************/
69433d6423SLionel Sambuc
70433d6423SLionel Sambuc ACPI_STATUS
AcpiExGetObjectReference(ACPI_OPERAND_OBJECT * ObjDesc,ACPI_OPERAND_OBJECT ** ReturnDesc,ACPI_WALK_STATE * WalkState)71433d6423SLionel Sambuc AcpiExGetObjectReference (
72433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *ObjDesc,
73433d6423SLionel Sambuc ACPI_OPERAND_OBJECT **ReturnDesc,
74433d6423SLionel Sambuc ACPI_WALK_STATE *WalkState)
75433d6423SLionel Sambuc {
76433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *ReferenceObj;
77433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *ReferencedObj;
78433d6423SLionel Sambuc
79433d6423SLionel Sambuc
80433d6423SLionel Sambuc ACPI_FUNCTION_TRACE_PTR (ExGetObjectReference, ObjDesc);
81433d6423SLionel Sambuc
82433d6423SLionel Sambuc
83433d6423SLionel Sambuc *ReturnDesc = NULL;
84433d6423SLionel Sambuc
85433d6423SLionel Sambuc switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
86433d6423SLionel Sambuc {
87433d6423SLionel Sambuc case ACPI_DESC_TYPE_OPERAND:
88433d6423SLionel Sambuc
89433d6423SLionel Sambuc if (ObjDesc->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
90433d6423SLionel Sambuc {
91433d6423SLionel Sambuc return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
92433d6423SLionel Sambuc }
93433d6423SLionel Sambuc
94433d6423SLionel Sambuc /*
95433d6423SLionel Sambuc * Must be a reference to a Local or Arg
96433d6423SLionel Sambuc */
97433d6423SLionel Sambuc switch (ObjDesc->Reference.Class)
98433d6423SLionel Sambuc {
99433d6423SLionel Sambuc case ACPI_REFCLASS_LOCAL:
100433d6423SLionel Sambuc case ACPI_REFCLASS_ARG:
101433d6423SLionel Sambuc case ACPI_REFCLASS_DEBUG:
102433d6423SLionel Sambuc
103433d6423SLionel Sambuc /* The referenced object is the pseudo-node for the local/arg */
104433d6423SLionel Sambuc
105433d6423SLionel Sambuc ReferencedObj = ObjDesc->Reference.Object;
106433d6423SLionel Sambuc break;
107433d6423SLionel Sambuc
108433d6423SLionel Sambuc default:
109433d6423SLionel Sambuc
110433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X",
111433d6423SLionel Sambuc ObjDesc->Reference.Class));
112433d6423SLionel Sambuc return_ACPI_STATUS (AE_AML_INTERNAL);
113433d6423SLionel Sambuc }
114433d6423SLionel Sambuc break;
115433d6423SLionel Sambuc
116433d6423SLionel Sambuc case ACPI_DESC_TYPE_NAMED:
117433d6423SLionel Sambuc /*
118433d6423SLionel Sambuc * A named reference that has already been resolved to a Node
119433d6423SLionel Sambuc */
120433d6423SLionel Sambuc ReferencedObj = ObjDesc;
121433d6423SLionel Sambuc break;
122433d6423SLionel Sambuc
123433d6423SLionel Sambuc default:
124433d6423SLionel Sambuc
125433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO, "Invalid descriptor type 0x%X",
126433d6423SLionel Sambuc ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)));
127433d6423SLionel Sambuc return_ACPI_STATUS (AE_TYPE);
128433d6423SLionel Sambuc }
129433d6423SLionel Sambuc
130433d6423SLionel Sambuc
131433d6423SLionel Sambuc /* Create a new reference object */
132433d6423SLionel Sambuc
133433d6423SLionel Sambuc ReferenceObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE);
134433d6423SLionel Sambuc if (!ReferenceObj)
135433d6423SLionel Sambuc {
136433d6423SLionel Sambuc return_ACPI_STATUS (AE_NO_MEMORY);
137433d6423SLionel Sambuc }
138433d6423SLionel Sambuc
139433d6423SLionel Sambuc ReferenceObj->Reference.Class = ACPI_REFCLASS_REFOF;
140433d6423SLionel Sambuc ReferenceObj->Reference.Object = ReferencedObj;
141433d6423SLionel Sambuc *ReturnDesc = ReferenceObj;
142433d6423SLionel Sambuc
143433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
144433d6423SLionel Sambuc "Object %p Type [%s], returning Reference %p\n",
145433d6423SLionel Sambuc ObjDesc, AcpiUtGetObjectTypeName (ObjDesc), *ReturnDesc));
146433d6423SLionel Sambuc
147433d6423SLionel Sambuc return_ACPI_STATUS (AE_OK);
148433d6423SLionel Sambuc }
149433d6423SLionel Sambuc
150433d6423SLionel Sambuc
151433d6423SLionel Sambuc /*******************************************************************************
152433d6423SLionel Sambuc *
153433d6423SLionel Sambuc * FUNCTION: AcpiExConcatTemplate
154433d6423SLionel Sambuc *
155433d6423SLionel Sambuc * PARAMETERS: Operand0 - First source object
156433d6423SLionel Sambuc * Operand1 - Second source object
157433d6423SLionel Sambuc * ActualReturnDesc - Where to place the return object
158433d6423SLionel Sambuc * WalkState - Current walk state
159433d6423SLionel Sambuc *
160433d6423SLionel Sambuc * RETURN: Status
161433d6423SLionel Sambuc *
162433d6423SLionel Sambuc * DESCRIPTION: Concatenate two resource templates
163433d6423SLionel Sambuc *
164433d6423SLionel Sambuc ******************************************************************************/
165433d6423SLionel Sambuc
166433d6423SLionel Sambuc ACPI_STATUS
AcpiExConcatTemplate(ACPI_OPERAND_OBJECT * Operand0,ACPI_OPERAND_OBJECT * Operand1,ACPI_OPERAND_OBJECT ** ActualReturnDesc,ACPI_WALK_STATE * WalkState)167433d6423SLionel Sambuc AcpiExConcatTemplate (
168433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *Operand0,
169433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *Operand1,
170433d6423SLionel Sambuc ACPI_OPERAND_OBJECT **ActualReturnDesc,
171433d6423SLionel Sambuc ACPI_WALK_STATE *WalkState)
172433d6423SLionel Sambuc {
173433d6423SLionel Sambuc ACPI_STATUS Status;
174433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *ReturnDesc;
175433d6423SLionel Sambuc UINT8 *NewBuf;
176433d6423SLionel Sambuc UINT8 *EndTag;
177433d6423SLionel Sambuc ACPI_SIZE Length0;
178433d6423SLionel Sambuc ACPI_SIZE Length1;
179433d6423SLionel Sambuc ACPI_SIZE NewLength;
180433d6423SLionel Sambuc
181433d6423SLionel Sambuc
182433d6423SLionel Sambuc ACPI_FUNCTION_TRACE (ExConcatTemplate);
183433d6423SLionel Sambuc
184433d6423SLionel Sambuc
185433d6423SLionel Sambuc /*
186433d6423SLionel Sambuc * Find the EndTag descriptor in each resource template.
187433d6423SLionel Sambuc * Note1: returned pointers point TO the EndTag, not past it.
188433d6423SLionel Sambuc * Note2: zero-length buffers are allowed; treated like one EndTag
189433d6423SLionel Sambuc */
190433d6423SLionel Sambuc
191433d6423SLionel Sambuc /* Get the length of the first resource template */
192433d6423SLionel Sambuc
193433d6423SLionel Sambuc Status = AcpiUtGetResourceEndTag (Operand0, &EndTag);
194433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
195433d6423SLionel Sambuc {
196433d6423SLionel Sambuc return_ACPI_STATUS (Status);
197433d6423SLionel Sambuc }
198433d6423SLionel Sambuc
199433d6423SLionel Sambuc Length0 = ACPI_PTR_DIFF (EndTag, Operand0->Buffer.Pointer);
200433d6423SLionel Sambuc
201433d6423SLionel Sambuc /* Get the length of the second resource template */
202433d6423SLionel Sambuc
203433d6423SLionel Sambuc Status = AcpiUtGetResourceEndTag (Operand1, &EndTag);
204433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
205433d6423SLionel Sambuc {
206433d6423SLionel Sambuc return_ACPI_STATUS (Status);
207433d6423SLionel Sambuc }
208433d6423SLionel Sambuc
209433d6423SLionel Sambuc Length1 = ACPI_PTR_DIFF (EndTag, Operand1->Buffer.Pointer);
210433d6423SLionel Sambuc
211433d6423SLionel Sambuc /* Combine both lengths, minimum size will be 2 for EndTag */
212433d6423SLionel Sambuc
213433d6423SLionel Sambuc NewLength = Length0 + Length1 + sizeof (AML_RESOURCE_END_TAG);
214433d6423SLionel Sambuc
215433d6423SLionel Sambuc /* Create a new buffer object for the result (with one EndTag) */
216433d6423SLionel Sambuc
217433d6423SLionel Sambuc ReturnDesc = AcpiUtCreateBufferObject (NewLength);
218433d6423SLionel Sambuc if (!ReturnDesc)
219433d6423SLionel Sambuc {
220433d6423SLionel Sambuc return_ACPI_STATUS (AE_NO_MEMORY);
221433d6423SLionel Sambuc }
222433d6423SLionel Sambuc
223433d6423SLionel Sambuc /*
224433d6423SLionel Sambuc * Copy the templates to the new buffer, 0 first, then 1 follows. One
225433d6423SLionel Sambuc * EndTag descriptor is copied from Operand1.
226433d6423SLionel Sambuc */
227433d6423SLionel Sambuc NewBuf = ReturnDesc->Buffer.Pointer;
228433d6423SLionel Sambuc ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer, Length0);
229433d6423SLionel Sambuc ACPI_MEMCPY (NewBuf + Length0, Operand1->Buffer.Pointer, Length1);
230433d6423SLionel Sambuc
231433d6423SLionel Sambuc /* Insert EndTag and set the checksum to zero, means "ignore checksum" */
232433d6423SLionel Sambuc
233433d6423SLionel Sambuc NewBuf[NewLength - 1] = 0;
234433d6423SLionel Sambuc NewBuf[NewLength - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
235433d6423SLionel Sambuc
236433d6423SLionel Sambuc /* Return the completed resource template */
237433d6423SLionel Sambuc
238433d6423SLionel Sambuc *ActualReturnDesc = ReturnDesc;
239433d6423SLionel Sambuc return_ACPI_STATUS (AE_OK);
240433d6423SLionel Sambuc }
241433d6423SLionel Sambuc
242433d6423SLionel Sambuc
243433d6423SLionel Sambuc /*******************************************************************************
244433d6423SLionel Sambuc *
245433d6423SLionel Sambuc * FUNCTION: AcpiExDoConcatenate
246433d6423SLionel Sambuc *
247433d6423SLionel Sambuc * PARAMETERS: Operand0 - First source object
248433d6423SLionel Sambuc * Operand1 - Second source object
249433d6423SLionel Sambuc * ActualReturnDesc - Where to place the return object
250433d6423SLionel Sambuc * WalkState - Current walk state
251433d6423SLionel Sambuc *
252433d6423SLionel Sambuc * RETURN: Status
253433d6423SLionel Sambuc *
254433d6423SLionel Sambuc * DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
255433d6423SLionel Sambuc *
256433d6423SLionel Sambuc ******************************************************************************/
257433d6423SLionel Sambuc
258433d6423SLionel Sambuc ACPI_STATUS
AcpiExDoConcatenate(ACPI_OPERAND_OBJECT * Operand0,ACPI_OPERAND_OBJECT * Operand1,ACPI_OPERAND_OBJECT ** ActualReturnDesc,ACPI_WALK_STATE * WalkState)259433d6423SLionel Sambuc AcpiExDoConcatenate (
260433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *Operand0,
261433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *Operand1,
262433d6423SLionel Sambuc ACPI_OPERAND_OBJECT **ActualReturnDesc,
263433d6423SLionel Sambuc ACPI_WALK_STATE *WalkState)
264433d6423SLionel Sambuc {
265433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *LocalOperand1 = Operand1;
266433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *ReturnDesc;
267433d6423SLionel Sambuc char *NewBuf;
268433d6423SLionel Sambuc ACPI_STATUS Status;
269433d6423SLionel Sambuc
270433d6423SLionel Sambuc
271433d6423SLionel Sambuc ACPI_FUNCTION_TRACE (ExDoConcatenate);
272433d6423SLionel Sambuc
273433d6423SLionel Sambuc
274433d6423SLionel Sambuc /*
275433d6423SLionel Sambuc * Convert the second operand if necessary. The first operand
276433d6423SLionel Sambuc * determines the type of the second operand, (See the Data Types
277433d6423SLionel Sambuc * section of the ACPI specification.) Both object types are
278433d6423SLionel Sambuc * guaranteed to be either Integer/String/Buffer by the operand
279433d6423SLionel Sambuc * resolution mechanism.
280433d6423SLionel Sambuc */
281433d6423SLionel Sambuc switch (Operand0->Common.Type)
282433d6423SLionel Sambuc {
283433d6423SLionel Sambuc case ACPI_TYPE_INTEGER:
284*29492bb7SDavid van Moolenbroek
285433d6423SLionel Sambuc Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16);
286433d6423SLionel Sambuc break;
287433d6423SLionel Sambuc
288433d6423SLionel Sambuc case ACPI_TYPE_STRING:
289*29492bb7SDavid van Moolenbroek
290433d6423SLionel Sambuc Status = AcpiExConvertToString (Operand1, &LocalOperand1,
291433d6423SLionel Sambuc ACPI_IMPLICIT_CONVERT_HEX);
292433d6423SLionel Sambuc break;
293433d6423SLionel Sambuc
294433d6423SLionel Sambuc case ACPI_TYPE_BUFFER:
295*29492bb7SDavid van Moolenbroek
296433d6423SLionel Sambuc Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1);
297433d6423SLionel Sambuc break;
298433d6423SLionel Sambuc
299433d6423SLionel Sambuc default:
300*29492bb7SDavid van Moolenbroek
301433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
302433d6423SLionel Sambuc Operand0->Common.Type));
303433d6423SLionel Sambuc Status = AE_AML_INTERNAL;
304433d6423SLionel Sambuc }
305433d6423SLionel Sambuc
306433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
307433d6423SLionel Sambuc {
308433d6423SLionel Sambuc goto Cleanup;
309433d6423SLionel Sambuc }
310433d6423SLionel Sambuc
311433d6423SLionel Sambuc /*
312433d6423SLionel Sambuc * Both operands are now known to be the same object type
313433d6423SLionel Sambuc * (Both are Integer, String, or Buffer), and we can now perform the
314433d6423SLionel Sambuc * concatenation.
315433d6423SLionel Sambuc */
316433d6423SLionel Sambuc
317433d6423SLionel Sambuc /*
318433d6423SLionel Sambuc * There are three cases to handle:
319433d6423SLionel Sambuc *
320433d6423SLionel Sambuc * 1) Two Integers concatenated to produce a new Buffer
321433d6423SLionel Sambuc * 2) Two Strings concatenated to produce a new String
322433d6423SLionel Sambuc * 3) Two Buffers concatenated to produce a new Buffer
323433d6423SLionel Sambuc */
324433d6423SLionel Sambuc switch (Operand0->Common.Type)
325433d6423SLionel Sambuc {
326433d6423SLionel Sambuc case ACPI_TYPE_INTEGER:
327433d6423SLionel Sambuc
328433d6423SLionel Sambuc /* Result of two Integers is a Buffer */
329433d6423SLionel Sambuc /* Need enough buffer space for two integers */
330433d6423SLionel Sambuc
331433d6423SLionel Sambuc ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE)
332433d6423SLionel Sambuc ACPI_MUL_2 (AcpiGbl_IntegerByteWidth));
333433d6423SLionel Sambuc if (!ReturnDesc)
334433d6423SLionel Sambuc {
335433d6423SLionel Sambuc Status = AE_NO_MEMORY;
336433d6423SLionel Sambuc goto Cleanup;
337433d6423SLionel Sambuc }
338433d6423SLionel Sambuc
339433d6423SLionel Sambuc NewBuf = (char *) ReturnDesc->Buffer.Pointer;
340433d6423SLionel Sambuc
341433d6423SLionel Sambuc /* Copy the first integer, LSB first */
342433d6423SLionel Sambuc
343433d6423SLionel Sambuc ACPI_MEMCPY (NewBuf, &Operand0->Integer.Value,
344433d6423SLionel Sambuc AcpiGbl_IntegerByteWidth);
345433d6423SLionel Sambuc
346433d6423SLionel Sambuc /* Copy the second integer (LSB first) after the first */
347433d6423SLionel Sambuc
348433d6423SLionel Sambuc ACPI_MEMCPY (NewBuf + AcpiGbl_IntegerByteWidth,
349433d6423SLionel Sambuc &LocalOperand1->Integer.Value,
350433d6423SLionel Sambuc AcpiGbl_IntegerByteWidth);
351433d6423SLionel Sambuc break;
352433d6423SLionel Sambuc
353433d6423SLionel Sambuc case ACPI_TYPE_STRING:
354433d6423SLionel Sambuc
355433d6423SLionel Sambuc /* Result of two Strings is a String */
356433d6423SLionel Sambuc
357433d6423SLionel Sambuc ReturnDesc = AcpiUtCreateStringObject (
358433d6423SLionel Sambuc ((ACPI_SIZE) Operand0->String.Length +
359433d6423SLionel Sambuc LocalOperand1->String.Length));
360433d6423SLionel Sambuc if (!ReturnDesc)
361433d6423SLionel Sambuc {
362433d6423SLionel Sambuc Status = AE_NO_MEMORY;
363433d6423SLionel Sambuc goto Cleanup;
364433d6423SLionel Sambuc }
365433d6423SLionel Sambuc
366433d6423SLionel Sambuc NewBuf = ReturnDesc->String.Pointer;
367433d6423SLionel Sambuc
368433d6423SLionel Sambuc /* Concatenate the strings */
369433d6423SLionel Sambuc
370433d6423SLionel Sambuc ACPI_STRCPY (NewBuf, Operand0->String.Pointer);
371433d6423SLionel Sambuc ACPI_STRCPY (NewBuf + Operand0->String.Length,
372433d6423SLionel Sambuc LocalOperand1->String.Pointer);
373433d6423SLionel Sambuc break;
374433d6423SLionel Sambuc
375433d6423SLionel Sambuc case ACPI_TYPE_BUFFER:
376433d6423SLionel Sambuc
377433d6423SLionel Sambuc /* Result of two Buffers is a Buffer */
378433d6423SLionel Sambuc
379433d6423SLionel Sambuc ReturnDesc = AcpiUtCreateBufferObject (
380433d6423SLionel Sambuc ((ACPI_SIZE) Operand0->Buffer.Length +
381433d6423SLionel Sambuc LocalOperand1->Buffer.Length));
382433d6423SLionel Sambuc if (!ReturnDesc)
383433d6423SLionel Sambuc {
384433d6423SLionel Sambuc Status = AE_NO_MEMORY;
385433d6423SLionel Sambuc goto Cleanup;
386433d6423SLionel Sambuc }
387433d6423SLionel Sambuc
388433d6423SLionel Sambuc NewBuf = (char *) ReturnDesc->Buffer.Pointer;
389433d6423SLionel Sambuc
390433d6423SLionel Sambuc /* Concatenate the buffers */
391433d6423SLionel Sambuc
392433d6423SLionel Sambuc ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer,
393433d6423SLionel Sambuc Operand0->Buffer.Length);
394433d6423SLionel Sambuc ACPI_MEMCPY (NewBuf + Operand0->Buffer.Length,
395433d6423SLionel Sambuc LocalOperand1->Buffer.Pointer,
396433d6423SLionel Sambuc LocalOperand1->Buffer.Length);
397433d6423SLionel Sambuc break;
398433d6423SLionel Sambuc
399433d6423SLionel Sambuc default:
400433d6423SLionel Sambuc
401433d6423SLionel Sambuc /* Invalid object type, should not happen here */
402433d6423SLionel Sambuc
403433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
404433d6423SLionel Sambuc Operand0->Common.Type));
405433d6423SLionel Sambuc Status =AE_AML_INTERNAL;
406433d6423SLionel Sambuc goto Cleanup;
407433d6423SLionel Sambuc }
408433d6423SLionel Sambuc
409433d6423SLionel Sambuc *ActualReturnDesc = ReturnDesc;
410433d6423SLionel Sambuc
411433d6423SLionel Sambuc Cleanup:
412433d6423SLionel Sambuc if (LocalOperand1 != Operand1)
413433d6423SLionel Sambuc {
414433d6423SLionel Sambuc AcpiUtRemoveReference (LocalOperand1);
415433d6423SLionel Sambuc }
416433d6423SLionel Sambuc return_ACPI_STATUS (Status);
417433d6423SLionel Sambuc }
418433d6423SLionel Sambuc
419433d6423SLionel Sambuc
420433d6423SLionel Sambuc /*******************************************************************************
421433d6423SLionel Sambuc *
422433d6423SLionel Sambuc * FUNCTION: AcpiExDoMathOp
423433d6423SLionel Sambuc *
424433d6423SLionel Sambuc * PARAMETERS: Opcode - AML opcode
425433d6423SLionel Sambuc * Integer0 - Integer operand #0
426433d6423SLionel Sambuc * Integer1 - Integer operand #1
427433d6423SLionel Sambuc *
428433d6423SLionel Sambuc * RETURN: Integer result of the operation
429433d6423SLionel Sambuc *
430433d6423SLionel Sambuc * DESCRIPTION: Execute a math AML opcode. The purpose of having all of the
431433d6423SLionel Sambuc * math functions here is to prevent a lot of pointer dereferencing
432433d6423SLionel Sambuc * to obtain the operands.
433433d6423SLionel Sambuc *
434433d6423SLionel Sambuc ******************************************************************************/
435433d6423SLionel Sambuc
436433d6423SLionel Sambuc UINT64
AcpiExDoMathOp(UINT16 Opcode,UINT64 Integer0,UINT64 Integer1)437433d6423SLionel Sambuc AcpiExDoMathOp (
438433d6423SLionel Sambuc UINT16 Opcode,
439433d6423SLionel Sambuc UINT64 Integer0,
440433d6423SLionel Sambuc UINT64 Integer1)
441433d6423SLionel Sambuc {
442433d6423SLionel Sambuc
443433d6423SLionel Sambuc ACPI_FUNCTION_ENTRY ();
444433d6423SLionel Sambuc
445433d6423SLionel Sambuc
446433d6423SLionel Sambuc switch (Opcode)
447433d6423SLionel Sambuc {
448433d6423SLionel Sambuc case AML_ADD_OP: /* Add (Integer0, Integer1, Result) */
449433d6423SLionel Sambuc
450433d6423SLionel Sambuc return (Integer0 + Integer1);
451433d6423SLionel Sambuc
452433d6423SLionel Sambuc case AML_BIT_AND_OP: /* And (Integer0, Integer1, Result) */
453433d6423SLionel Sambuc
454433d6423SLionel Sambuc return (Integer0 & Integer1);
455433d6423SLionel Sambuc
456433d6423SLionel Sambuc case AML_BIT_NAND_OP: /* NAnd (Integer0, Integer1, Result) */
457433d6423SLionel Sambuc
458433d6423SLionel Sambuc return (~(Integer0 & Integer1));
459433d6423SLionel Sambuc
460433d6423SLionel Sambuc case AML_BIT_OR_OP: /* Or (Integer0, Integer1, Result) */
461433d6423SLionel Sambuc
462433d6423SLionel Sambuc return (Integer0 | Integer1);
463433d6423SLionel Sambuc
464433d6423SLionel Sambuc case AML_BIT_NOR_OP: /* NOr (Integer0, Integer1, Result) */
465433d6423SLionel Sambuc
466433d6423SLionel Sambuc return (~(Integer0 | Integer1));
467433d6423SLionel Sambuc
468433d6423SLionel Sambuc case AML_BIT_XOR_OP: /* XOr (Integer0, Integer1, Result) */
469433d6423SLionel Sambuc
470433d6423SLionel Sambuc return (Integer0 ^ Integer1);
471433d6423SLionel Sambuc
472433d6423SLionel Sambuc case AML_MULTIPLY_OP: /* Multiply (Integer0, Integer1, Result) */
473433d6423SLionel Sambuc
474433d6423SLionel Sambuc return (Integer0 * Integer1);
475433d6423SLionel Sambuc
476433d6423SLionel Sambuc case AML_SHIFT_LEFT_OP: /* ShiftLeft (Operand, ShiftCount, Result)*/
477433d6423SLionel Sambuc
478433d6423SLionel Sambuc /*
479433d6423SLionel Sambuc * We need to check if the shiftcount is larger than the integer bit
480433d6423SLionel Sambuc * width since the behavior of this is not well-defined in the C language.
481433d6423SLionel Sambuc */
482433d6423SLionel Sambuc if (Integer1 >= AcpiGbl_IntegerBitWidth)
483433d6423SLionel Sambuc {
484433d6423SLionel Sambuc return (0);
485433d6423SLionel Sambuc }
486433d6423SLionel Sambuc return (Integer0 << Integer1);
487433d6423SLionel Sambuc
488433d6423SLionel Sambuc case AML_SHIFT_RIGHT_OP: /* ShiftRight (Operand, ShiftCount, Result) */
489433d6423SLionel Sambuc
490433d6423SLionel Sambuc /*
491433d6423SLionel Sambuc * We need to check if the shiftcount is larger than the integer bit
492433d6423SLionel Sambuc * width since the behavior of this is not well-defined in the C language.
493433d6423SLionel Sambuc */
494433d6423SLionel Sambuc if (Integer1 >= AcpiGbl_IntegerBitWidth)
495433d6423SLionel Sambuc {
496433d6423SLionel Sambuc return (0);
497433d6423SLionel Sambuc }
498433d6423SLionel Sambuc return (Integer0 >> Integer1);
499433d6423SLionel Sambuc
500433d6423SLionel Sambuc case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */
501433d6423SLionel Sambuc
502433d6423SLionel Sambuc return (Integer0 - Integer1);
503433d6423SLionel Sambuc
504433d6423SLionel Sambuc default:
505433d6423SLionel Sambuc
506433d6423SLionel Sambuc return (0);
507433d6423SLionel Sambuc }
508433d6423SLionel Sambuc }
509433d6423SLionel Sambuc
510433d6423SLionel Sambuc
511433d6423SLionel Sambuc /*******************************************************************************
512433d6423SLionel Sambuc *
513433d6423SLionel Sambuc * FUNCTION: AcpiExDoLogicalNumericOp
514433d6423SLionel Sambuc *
515433d6423SLionel Sambuc * PARAMETERS: Opcode - AML opcode
516433d6423SLionel Sambuc * Integer0 - Integer operand #0
517433d6423SLionel Sambuc * Integer1 - Integer operand #1
518433d6423SLionel Sambuc * LogicalResult - TRUE/FALSE result of the operation
519433d6423SLionel Sambuc *
520433d6423SLionel Sambuc * RETURN: Status
521433d6423SLionel Sambuc *
522433d6423SLionel Sambuc * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric
523433d6423SLionel Sambuc * operators (LAnd and LOr), both operands must be integers.
524433d6423SLionel Sambuc *
525433d6423SLionel Sambuc * Note: cleanest machine code seems to be produced by the code
526433d6423SLionel Sambuc * below, rather than using statements of the form:
527433d6423SLionel Sambuc * Result = (Integer0 && Integer1);
528433d6423SLionel Sambuc *
529433d6423SLionel Sambuc ******************************************************************************/
530433d6423SLionel Sambuc
531433d6423SLionel Sambuc ACPI_STATUS
AcpiExDoLogicalNumericOp(UINT16 Opcode,UINT64 Integer0,UINT64 Integer1,BOOLEAN * LogicalResult)532433d6423SLionel Sambuc AcpiExDoLogicalNumericOp (
533433d6423SLionel Sambuc UINT16 Opcode,
534433d6423SLionel Sambuc UINT64 Integer0,
535433d6423SLionel Sambuc UINT64 Integer1,
536433d6423SLionel Sambuc BOOLEAN *LogicalResult)
537433d6423SLionel Sambuc {
538433d6423SLionel Sambuc ACPI_STATUS Status = AE_OK;
539433d6423SLionel Sambuc BOOLEAN LocalResult = FALSE;
540433d6423SLionel Sambuc
541433d6423SLionel Sambuc
542433d6423SLionel Sambuc ACPI_FUNCTION_TRACE (ExDoLogicalNumericOp);
543433d6423SLionel Sambuc
544433d6423SLionel Sambuc
545433d6423SLionel Sambuc switch (Opcode)
546433d6423SLionel Sambuc {
547433d6423SLionel Sambuc case AML_LAND_OP: /* LAnd (Integer0, Integer1) */
548433d6423SLionel Sambuc
549433d6423SLionel Sambuc if (Integer0 && Integer1)
550433d6423SLionel Sambuc {
551433d6423SLionel Sambuc LocalResult = TRUE;
552433d6423SLionel Sambuc }
553433d6423SLionel Sambuc break;
554433d6423SLionel Sambuc
555433d6423SLionel Sambuc case AML_LOR_OP: /* LOr (Integer0, Integer1) */
556433d6423SLionel Sambuc
557433d6423SLionel Sambuc if (Integer0 || Integer1)
558433d6423SLionel Sambuc {
559433d6423SLionel Sambuc LocalResult = TRUE;
560433d6423SLionel Sambuc }
561433d6423SLionel Sambuc break;
562433d6423SLionel Sambuc
563433d6423SLionel Sambuc default:
564*29492bb7SDavid van Moolenbroek
565433d6423SLionel Sambuc Status = AE_AML_INTERNAL;
566433d6423SLionel Sambuc break;
567433d6423SLionel Sambuc }
568433d6423SLionel Sambuc
569433d6423SLionel Sambuc /* Return the logical result and status */
570433d6423SLionel Sambuc
571433d6423SLionel Sambuc *LogicalResult = LocalResult;
572433d6423SLionel Sambuc return_ACPI_STATUS (Status);
573433d6423SLionel Sambuc }
574433d6423SLionel Sambuc
575433d6423SLionel Sambuc
576433d6423SLionel Sambuc /*******************************************************************************
577433d6423SLionel Sambuc *
578433d6423SLionel Sambuc * FUNCTION: AcpiExDoLogicalOp
579433d6423SLionel Sambuc *
580433d6423SLionel Sambuc * PARAMETERS: Opcode - AML opcode
581433d6423SLionel Sambuc * Operand0 - operand #0
582433d6423SLionel Sambuc * Operand1 - operand #1
583433d6423SLionel Sambuc * LogicalResult - TRUE/FALSE result of the operation
584433d6423SLionel Sambuc *
585433d6423SLionel Sambuc * RETURN: Status
586433d6423SLionel Sambuc *
587433d6423SLionel Sambuc * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the
588433d6423SLionel Sambuc * functions here is to prevent a lot of pointer dereferencing
589433d6423SLionel Sambuc * to obtain the operands and to simplify the generation of the
590433d6423SLionel Sambuc * logical value. For the Numeric operators (LAnd and LOr), both
591433d6423SLionel Sambuc * operands must be integers. For the other logical operators,
592433d6423SLionel Sambuc * operands can be any combination of Integer/String/Buffer. The
593433d6423SLionel Sambuc * first operand determines the type to which the second operand
594433d6423SLionel Sambuc * will be converted.
595433d6423SLionel Sambuc *
596433d6423SLionel Sambuc * Note: cleanest machine code seems to be produced by the code
597433d6423SLionel Sambuc * below, rather than using statements of the form:
598433d6423SLionel Sambuc * Result = (Operand0 == Operand1);
599433d6423SLionel Sambuc *
600433d6423SLionel Sambuc ******************************************************************************/
601433d6423SLionel Sambuc
602433d6423SLionel Sambuc ACPI_STATUS
AcpiExDoLogicalOp(UINT16 Opcode,ACPI_OPERAND_OBJECT * Operand0,ACPI_OPERAND_OBJECT * Operand1,BOOLEAN * LogicalResult)603433d6423SLionel Sambuc AcpiExDoLogicalOp (
604433d6423SLionel Sambuc UINT16 Opcode,
605433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *Operand0,
606433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *Operand1,
607433d6423SLionel Sambuc BOOLEAN *LogicalResult)
608433d6423SLionel Sambuc {
609433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *LocalOperand1 = Operand1;
610433d6423SLionel Sambuc UINT64 Integer0;
611433d6423SLionel Sambuc UINT64 Integer1;
612433d6423SLionel Sambuc UINT32 Length0;
613433d6423SLionel Sambuc UINT32 Length1;
614433d6423SLionel Sambuc ACPI_STATUS Status = AE_OK;
615433d6423SLionel Sambuc BOOLEAN LocalResult = FALSE;
616433d6423SLionel Sambuc int Compare;
617433d6423SLionel Sambuc
618433d6423SLionel Sambuc
619433d6423SLionel Sambuc ACPI_FUNCTION_TRACE (ExDoLogicalOp);
620433d6423SLionel Sambuc
621433d6423SLionel Sambuc
622433d6423SLionel Sambuc /*
623433d6423SLionel Sambuc * Convert the second operand if necessary. The first operand
624433d6423SLionel Sambuc * determines the type of the second operand, (See the Data Types
625433d6423SLionel Sambuc * section of the ACPI 3.0+ specification.) Both object types are
626433d6423SLionel Sambuc * guaranteed to be either Integer/String/Buffer by the operand
627433d6423SLionel Sambuc * resolution mechanism.
628433d6423SLionel Sambuc */
629433d6423SLionel Sambuc switch (Operand0->Common.Type)
630433d6423SLionel Sambuc {
631433d6423SLionel Sambuc case ACPI_TYPE_INTEGER:
632*29492bb7SDavid van Moolenbroek
633433d6423SLionel Sambuc Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16);
634433d6423SLionel Sambuc break;
635433d6423SLionel Sambuc
636433d6423SLionel Sambuc case ACPI_TYPE_STRING:
637*29492bb7SDavid van Moolenbroek
638433d6423SLionel Sambuc Status = AcpiExConvertToString (Operand1, &LocalOperand1,
639433d6423SLionel Sambuc ACPI_IMPLICIT_CONVERT_HEX);
640433d6423SLionel Sambuc break;
641433d6423SLionel Sambuc
642433d6423SLionel Sambuc case ACPI_TYPE_BUFFER:
643*29492bb7SDavid van Moolenbroek
644433d6423SLionel Sambuc Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1);
645433d6423SLionel Sambuc break;
646433d6423SLionel Sambuc
647433d6423SLionel Sambuc default:
648*29492bb7SDavid van Moolenbroek
649433d6423SLionel Sambuc Status = AE_AML_INTERNAL;
650433d6423SLionel Sambuc break;
651433d6423SLionel Sambuc }
652433d6423SLionel Sambuc
653433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
654433d6423SLionel Sambuc {
655433d6423SLionel Sambuc goto Cleanup;
656433d6423SLionel Sambuc }
657433d6423SLionel Sambuc
658433d6423SLionel Sambuc /*
659433d6423SLionel Sambuc * Two cases: 1) Both Integers, 2) Both Strings or Buffers
660433d6423SLionel Sambuc */
661433d6423SLionel Sambuc if (Operand0->Common.Type == ACPI_TYPE_INTEGER)
662433d6423SLionel Sambuc {
663433d6423SLionel Sambuc /*
664433d6423SLionel Sambuc * 1) Both operands are of type integer
665433d6423SLionel Sambuc * Note: LocalOperand1 may have changed above
666433d6423SLionel Sambuc */
667433d6423SLionel Sambuc Integer0 = Operand0->Integer.Value;
668433d6423SLionel Sambuc Integer1 = LocalOperand1->Integer.Value;
669433d6423SLionel Sambuc
670433d6423SLionel Sambuc switch (Opcode)
671433d6423SLionel Sambuc {
672433d6423SLionel Sambuc case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
673433d6423SLionel Sambuc
674433d6423SLionel Sambuc if (Integer0 == Integer1)
675433d6423SLionel Sambuc {
676433d6423SLionel Sambuc LocalResult = TRUE;
677433d6423SLionel Sambuc }
678433d6423SLionel Sambuc break;
679433d6423SLionel Sambuc
680433d6423SLionel Sambuc case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
681433d6423SLionel Sambuc
682433d6423SLionel Sambuc if (Integer0 > Integer1)
683433d6423SLionel Sambuc {
684433d6423SLionel Sambuc LocalResult = TRUE;
685433d6423SLionel Sambuc }
686433d6423SLionel Sambuc break;
687433d6423SLionel Sambuc
688433d6423SLionel Sambuc case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
689433d6423SLionel Sambuc
690433d6423SLionel Sambuc if (Integer0 < Integer1)
691433d6423SLionel Sambuc {
692433d6423SLionel Sambuc LocalResult = TRUE;
693433d6423SLionel Sambuc }
694433d6423SLionel Sambuc break;
695433d6423SLionel Sambuc
696433d6423SLionel Sambuc default:
697*29492bb7SDavid van Moolenbroek
698433d6423SLionel Sambuc Status = AE_AML_INTERNAL;
699433d6423SLionel Sambuc break;
700433d6423SLionel Sambuc }
701433d6423SLionel Sambuc }
702433d6423SLionel Sambuc else
703433d6423SLionel Sambuc {
704433d6423SLionel Sambuc /*
705433d6423SLionel Sambuc * 2) Both operands are Strings or both are Buffers
706433d6423SLionel Sambuc * Note: Code below takes advantage of common Buffer/String
707433d6423SLionel Sambuc * object fields. LocalOperand1 may have changed above. Use
708433d6423SLionel Sambuc * memcmp to handle nulls in buffers.
709433d6423SLionel Sambuc */
710433d6423SLionel Sambuc Length0 = Operand0->Buffer.Length;
711433d6423SLionel Sambuc Length1 = LocalOperand1->Buffer.Length;
712433d6423SLionel Sambuc
713433d6423SLionel Sambuc /* Lexicographic compare: compare the data bytes */
714433d6423SLionel Sambuc
715433d6423SLionel Sambuc Compare = ACPI_MEMCMP (Operand0->Buffer.Pointer,
716433d6423SLionel Sambuc LocalOperand1->Buffer.Pointer,
717433d6423SLionel Sambuc (Length0 > Length1) ? Length1 : Length0);
718433d6423SLionel Sambuc
719433d6423SLionel Sambuc switch (Opcode)
720433d6423SLionel Sambuc {
721433d6423SLionel Sambuc case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
722433d6423SLionel Sambuc
723433d6423SLionel Sambuc /* Length and all bytes must be equal */
724433d6423SLionel Sambuc
725433d6423SLionel Sambuc if ((Length0 == Length1) &&
726433d6423SLionel Sambuc (Compare == 0))
727433d6423SLionel Sambuc {
728433d6423SLionel Sambuc /* Length and all bytes match ==> TRUE */
729433d6423SLionel Sambuc
730433d6423SLionel Sambuc LocalResult = TRUE;
731433d6423SLionel Sambuc }
732433d6423SLionel Sambuc break;
733433d6423SLionel Sambuc
734433d6423SLionel Sambuc case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
735433d6423SLionel Sambuc
736433d6423SLionel Sambuc if (Compare > 0)
737433d6423SLionel Sambuc {
738433d6423SLionel Sambuc LocalResult = TRUE;
739433d6423SLionel Sambuc goto Cleanup; /* TRUE */
740433d6423SLionel Sambuc }
741433d6423SLionel Sambuc if (Compare < 0)
742433d6423SLionel Sambuc {
743433d6423SLionel Sambuc goto Cleanup; /* FALSE */
744433d6423SLionel Sambuc }
745433d6423SLionel Sambuc
746433d6423SLionel Sambuc /* Bytes match (to shortest length), compare lengths */
747433d6423SLionel Sambuc
748433d6423SLionel Sambuc if (Length0 > Length1)
749433d6423SLionel Sambuc {
750433d6423SLionel Sambuc LocalResult = TRUE;
751433d6423SLionel Sambuc }
752433d6423SLionel Sambuc break;
753433d6423SLionel Sambuc
754433d6423SLionel Sambuc case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
755433d6423SLionel Sambuc
756433d6423SLionel Sambuc if (Compare > 0)
757433d6423SLionel Sambuc {
758433d6423SLionel Sambuc goto Cleanup; /* FALSE */
759433d6423SLionel Sambuc }
760433d6423SLionel Sambuc if (Compare < 0)
761433d6423SLionel Sambuc {
762433d6423SLionel Sambuc LocalResult = TRUE;
763433d6423SLionel Sambuc goto Cleanup; /* TRUE */
764433d6423SLionel Sambuc }
765433d6423SLionel Sambuc
766433d6423SLionel Sambuc /* Bytes match (to shortest length), compare lengths */
767433d6423SLionel Sambuc
768433d6423SLionel Sambuc if (Length0 < Length1)
769433d6423SLionel Sambuc {
770433d6423SLionel Sambuc LocalResult = TRUE;
771433d6423SLionel Sambuc }
772433d6423SLionel Sambuc break;
773433d6423SLionel Sambuc
774433d6423SLionel Sambuc default:
775*29492bb7SDavid van Moolenbroek
776433d6423SLionel Sambuc Status = AE_AML_INTERNAL;
777433d6423SLionel Sambuc break;
778433d6423SLionel Sambuc }
779433d6423SLionel Sambuc }
780433d6423SLionel Sambuc
781433d6423SLionel Sambuc Cleanup:
782433d6423SLionel Sambuc
783433d6423SLionel Sambuc /* New object was created if implicit conversion performed - delete */
784433d6423SLionel Sambuc
785433d6423SLionel Sambuc if (LocalOperand1 != Operand1)
786433d6423SLionel Sambuc {
787433d6423SLionel Sambuc AcpiUtRemoveReference (LocalOperand1);
788433d6423SLionel Sambuc }
789433d6423SLionel Sambuc
790433d6423SLionel Sambuc /* Return the logical result and status */
791433d6423SLionel Sambuc
792433d6423SLionel Sambuc *LogicalResult = LocalResult;
793433d6423SLionel Sambuc return_ACPI_STATUS (Status);
794433d6423SLionel Sambuc }
795