1*bc36eafdSMike Gerdts /****************************************************************************** 2*bc36eafdSMike Gerdts * 3*bc36eafdSMike Gerdts * Module Name: dtexpress.c - Support for integer expressions and labels 4*bc36eafdSMike Gerdts * 5*bc36eafdSMike Gerdts *****************************************************************************/ 6*bc36eafdSMike Gerdts 7*bc36eafdSMike Gerdts /* 8*bc36eafdSMike Gerdts * Copyright (C) 2000 - 2016, Intel Corp. 9*bc36eafdSMike Gerdts * All rights reserved. 10*bc36eafdSMike Gerdts * 11*bc36eafdSMike Gerdts * Redistribution and use in source and binary forms, with or without 12*bc36eafdSMike Gerdts * modification, are permitted provided that the following conditions 13*bc36eafdSMike Gerdts * are met: 14*bc36eafdSMike Gerdts * 1. Redistributions of source code must retain the above copyright 15*bc36eafdSMike Gerdts * notice, this list of conditions, and the following disclaimer, 16*bc36eafdSMike Gerdts * without modification. 17*bc36eafdSMike Gerdts * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18*bc36eafdSMike Gerdts * substantially similar to the "NO WARRANTY" disclaimer below 19*bc36eafdSMike Gerdts * ("Disclaimer") and any redistribution must be conditioned upon 20*bc36eafdSMike Gerdts * including a substantially similar Disclaimer requirement for further 21*bc36eafdSMike Gerdts * binary redistribution. 22*bc36eafdSMike Gerdts * 3. Neither the names of the above-listed copyright holders nor the names 23*bc36eafdSMike Gerdts * of any contributors may be used to endorse or promote products derived 24*bc36eafdSMike Gerdts * from this software without specific prior written permission. 25*bc36eafdSMike Gerdts * 26*bc36eafdSMike Gerdts * Alternatively, this software may be distributed under the terms of the 27*bc36eafdSMike Gerdts * GNU General Public License ("GPL") version 2 as published by the Free 28*bc36eafdSMike Gerdts * Software Foundation. 29*bc36eafdSMike Gerdts * 30*bc36eafdSMike Gerdts * NO WARRANTY 31*bc36eafdSMike Gerdts * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32*bc36eafdSMike Gerdts * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33*bc36eafdSMike Gerdts * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34*bc36eafdSMike Gerdts * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35*bc36eafdSMike Gerdts * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36*bc36eafdSMike Gerdts * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37*bc36eafdSMike Gerdts * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38*bc36eafdSMike Gerdts * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39*bc36eafdSMike Gerdts * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40*bc36eafdSMike Gerdts * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41*bc36eafdSMike Gerdts * POSSIBILITY OF SUCH DAMAGES. 42*bc36eafdSMike Gerdts */ 43*bc36eafdSMike Gerdts 44*bc36eafdSMike Gerdts #include "aslcompiler.h" 45*bc36eafdSMike Gerdts #include "dtcompiler.h" 46*bc36eafdSMike Gerdts #include "dtparser.y.h" 47*bc36eafdSMike Gerdts 48*bc36eafdSMike Gerdts #define _COMPONENT DT_COMPILER 49*bc36eafdSMike Gerdts ACPI_MODULE_NAME ("dtexpress") 50*bc36eafdSMike Gerdts 51*bc36eafdSMike Gerdts 52*bc36eafdSMike Gerdts /* Local prototypes */ 53*bc36eafdSMike Gerdts 54*bc36eafdSMike Gerdts static void 55*bc36eafdSMike Gerdts DtInsertLabelField ( 56*bc36eafdSMike Gerdts DT_FIELD *Field); 57*bc36eafdSMike Gerdts 58*bc36eafdSMike Gerdts static DT_FIELD * 59*bc36eafdSMike Gerdts DtLookupLabel ( 60*bc36eafdSMike Gerdts char *Name); 61*bc36eafdSMike Gerdts 62*bc36eafdSMike Gerdts /* Global used for errors during parse and related functions */ 63*bc36eafdSMike Gerdts 64*bc36eafdSMike Gerdts DT_FIELD *Gbl_CurrentField; 65*bc36eafdSMike Gerdts 66*bc36eafdSMike Gerdts 67*bc36eafdSMike Gerdts /****************************************************************************** 68*bc36eafdSMike Gerdts * 69*bc36eafdSMike Gerdts * FUNCTION: DtResolveIntegerExpression 70*bc36eafdSMike Gerdts * 71*bc36eafdSMike Gerdts * PARAMETERS: Field - Field object with Integer expression 72*bc36eafdSMike Gerdts * ReturnValue - Where the integer is returned 73*bc36eafdSMike Gerdts * 74*bc36eafdSMike Gerdts * RETURN: Status, and the resolved 64-bit integer value 75*bc36eafdSMike Gerdts * 76*bc36eafdSMike Gerdts * DESCRIPTION: Resolve an integer expression to a single value. Supports 77*bc36eafdSMike Gerdts * both integer constants and labels. 78*bc36eafdSMike Gerdts * 79*bc36eafdSMike Gerdts *****************************************************************************/ 80*bc36eafdSMike Gerdts 81*bc36eafdSMike Gerdts ACPI_STATUS 82*bc36eafdSMike Gerdts DtResolveIntegerExpression ( 83*bc36eafdSMike Gerdts DT_FIELD *Field, 84*bc36eafdSMike Gerdts UINT64 *ReturnValue) 85*bc36eafdSMike Gerdts { 86*bc36eafdSMike Gerdts UINT64 Result; 87*bc36eafdSMike Gerdts 88*bc36eafdSMike Gerdts 89*bc36eafdSMike Gerdts DbgPrint (ASL_DEBUG_OUTPUT, "Full Integer expression: %s\n", 90*bc36eafdSMike Gerdts Field->Value); 91*bc36eafdSMike Gerdts 92*bc36eafdSMike Gerdts Gbl_CurrentField = Field; 93*bc36eafdSMike Gerdts 94*bc36eafdSMike Gerdts Result = DtEvaluateExpression (Field->Value); 95*bc36eafdSMike Gerdts *ReturnValue = Result; 96*bc36eafdSMike Gerdts return (AE_OK); 97*bc36eafdSMike Gerdts } 98*bc36eafdSMike Gerdts 99*bc36eafdSMike Gerdts 100*bc36eafdSMike Gerdts /****************************************************************************** 101*bc36eafdSMike Gerdts * 102*bc36eafdSMike Gerdts * FUNCTION: DtDoOperator 103*bc36eafdSMike Gerdts * 104*bc36eafdSMike Gerdts * PARAMETERS: LeftValue - First 64-bit operand 105*bc36eafdSMike Gerdts * Operator - Parse token for the operator (EXPOP_*) 106*bc36eafdSMike Gerdts * RightValue - Second 64-bit operand 107*bc36eafdSMike Gerdts * 108*bc36eafdSMike Gerdts * RETURN: 64-bit result of the requested operation 109*bc36eafdSMike Gerdts * 110*bc36eafdSMike Gerdts * DESCRIPTION: Perform the various 64-bit integer math functions 111*bc36eafdSMike Gerdts * 112*bc36eafdSMike Gerdts *****************************************************************************/ 113*bc36eafdSMike Gerdts 114*bc36eafdSMike Gerdts UINT64 115*bc36eafdSMike Gerdts DtDoOperator ( 116*bc36eafdSMike Gerdts UINT64 LeftValue, 117*bc36eafdSMike Gerdts UINT32 Operator, 118*bc36eafdSMike Gerdts UINT64 RightValue) 119*bc36eafdSMike Gerdts { 120*bc36eafdSMike Gerdts UINT64 Result; 121*bc36eafdSMike Gerdts 122*bc36eafdSMike Gerdts 123*bc36eafdSMike Gerdts /* Perform the requested operation */ 124*bc36eafdSMike Gerdts 125*bc36eafdSMike Gerdts switch (Operator) 126*bc36eafdSMike Gerdts { 127*bc36eafdSMike Gerdts case EXPOP_ONES_COMPLIMENT: 128*bc36eafdSMike Gerdts 129*bc36eafdSMike Gerdts Result = ~RightValue; 130*bc36eafdSMike Gerdts break; 131*bc36eafdSMike Gerdts 132*bc36eafdSMike Gerdts case EXPOP_LOGICAL_NOT: 133*bc36eafdSMike Gerdts 134*bc36eafdSMike Gerdts Result = !RightValue; 135*bc36eafdSMike Gerdts break; 136*bc36eafdSMike Gerdts 137*bc36eafdSMike Gerdts case EXPOP_MULTIPLY: 138*bc36eafdSMike Gerdts 139*bc36eafdSMike Gerdts Result = LeftValue * RightValue; 140*bc36eafdSMike Gerdts break; 141*bc36eafdSMike Gerdts 142*bc36eafdSMike Gerdts case EXPOP_DIVIDE: 143*bc36eafdSMike Gerdts 144*bc36eafdSMike Gerdts if (!RightValue) 145*bc36eafdSMike Gerdts { 146*bc36eafdSMike Gerdts DtError (ASL_ERROR, ASL_MSG_DIVIDE_BY_ZERO, 147*bc36eafdSMike Gerdts Gbl_CurrentField, NULL); 148*bc36eafdSMike Gerdts return (0); 149*bc36eafdSMike Gerdts } 150*bc36eafdSMike Gerdts 151*bc36eafdSMike Gerdts Result = LeftValue / RightValue; 152*bc36eafdSMike Gerdts break; 153*bc36eafdSMike Gerdts 154*bc36eafdSMike Gerdts case EXPOP_MODULO: 155*bc36eafdSMike Gerdts 156*bc36eafdSMike Gerdts if (!RightValue) 157*bc36eafdSMike Gerdts { 158*bc36eafdSMike Gerdts DtError (ASL_ERROR, ASL_MSG_DIVIDE_BY_ZERO, 159*bc36eafdSMike Gerdts Gbl_CurrentField, NULL); 160*bc36eafdSMike Gerdts return (0); 161*bc36eafdSMike Gerdts } 162*bc36eafdSMike Gerdts 163*bc36eafdSMike Gerdts Result = LeftValue % RightValue; 164*bc36eafdSMike Gerdts break; 165*bc36eafdSMike Gerdts 166*bc36eafdSMike Gerdts case EXPOP_ADD: 167*bc36eafdSMike Gerdts Result = LeftValue + RightValue; 168*bc36eafdSMike Gerdts break; 169*bc36eafdSMike Gerdts 170*bc36eafdSMike Gerdts case EXPOP_SUBTRACT: 171*bc36eafdSMike Gerdts 172*bc36eafdSMike Gerdts Result = LeftValue - RightValue; 173*bc36eafdSMike Gerdts break; 174*bc36eafdSMike Gerdts 175*bc36eafdSMike Gerdts case EXPOP_SHIFT_RIGHT: 176*bc36eafdSMike Gerdts 177*bc36eafdSMike Gerdts Result = LeftValue >> RightValue; 178*bc36eafdSMike Gerdts break; 179*bc36eafdSMike Gerdts 180*bc36eafdSMike Gerdts case EXPOP_SHIFT_LEFT: 181*bc36eafdSMike Gerdts 182*bc36eafdSMike Gerdts Result = LeftValue << RightValue; 183*bc36eafdSMike Gerdts break; 184*bc36eafdSMike Gerdts 185*bc36eafdSMike Gerdts case EXPOP_LESS: 186*bc36eafdSMike Gerdts 187*bc36eafdSMike Gerdts Result = LeftValue < RightValue; 188*bc36eafdSMike Gerdts break; 189*bc36eafdSMike Gerdts 190*bc36eafdSMike Gerdts case EXPOP_GREATER: 191*bc36eafdSMike Gerdts 192*bc36eafdSMike Gerdts Result = LeftValue > RightValue; 193*bc36eafdSMike Gerdts break; 194*bc36eafdSMike Gerdts 195*bc36eafdSMike Gerdts case EXPOP_LESS_EQUAL: 196*bc36eafdSMike Gerdts 197*bc36eafdSMike Gerdts Result = LeftValue <= RightValue; 198*bc36eafdSMike Gerdts break; 199*bc36eafdSMike Gerdts 200*bc36eafdSMike Gerdts case EXPOP_GREATER_EQUAL: 201*bc36eafdSMike Gerdts 202*bc36eafdSMike Gerdts Result = LeftValue >= RightValue; 203*bc36eafdSMike Gerdts break; 204*bc36eafdSMike Gerdts 205*bc36eafdSMike Gerdts case EXPOP_EQUAL: 206*bc36eafdSMike Gerdts 207*bc36eafdSMike Gerdts Result = LeftValue == RightValue; 208*bc36eafdSMike Gerdts break; 209*bc36eafdSMike Gerdts 210*bc36eafdSMike Gerdts case EXPOP_NOT_EQUAL: 211*bc36eafdSMike Gerdts 212*bc36eafdSMike Gerdts Result = LeftValue != RightValue; 213*bc36eafdSMike Gerdts break; 214*bc36eafdSMike Gerdts 215*bc36eafdSMike Gerdts case EXPOP_AND: 216*bc36eafdSMike Gerdts 217*bc36eafdSMike Gerdts Result = LeftValue & RightValue; 218*bc36eafdSMike Gerdts break; 219*bc36eafdSMike Gerdts 220*bc36eafdSMike Gerdts case EXPOP_XOR: 221*bc36eafdSMike Gerdts 222*bc36eafdSMike Gerdts Result = LeftValue ^ RightValue; 223*bc36eafdSMike Gerdts break; 224*bc36eafdSMike Gerdts 225*bc36eafdSMike Gerdts case EXPOP_OR: 226*bc36eafdSMike Gerdts 227*bc36eafdSMike Gerdts Result = LeftValue | RightValue; 228*bc36eafdSMike Gerdts break; 229*bc36eafdSMike Gerdts 230*bc36eafdSMike Gerdts case EXPOP_LOGICAL_AND: 231*bc36eafdSMike Gerdts 232*bc36eafdSMike Gerdts Result = LeftValue && RightValue; 233*bc36eafdSMike Gerdts break; 234*bc36eafdSMike Gerdts 235*bc36eafdSMike Gerdts case EXPOP_LOGICAL_OR: 236*bc36eafdSMike Gerdts 237*bc36eafdSMike Gerdts Result = LeftValue || RightValue; 238*bc36eafdSMike Gerdts break; 239*bc36eafdSMike Gerdts 240*bc36eafdSMike Gerdts default: 241*bc36eafdSMike Gerdts 242*bc36eafdSMike Gerdts /* Unknown operator */ 243*bc36eafdSMike Gerdts 244*bc36eafdSMike Gerdts DtFatal (ASL_MSG_INVALID_EXPRESSION, 245*bc36eafdSMike Gerdts Gbl_CurrentField, NULL); 246*bc36eafdSMike Gerdts return (0); 247*bc36eafdSMike Gerdts } 248*bc36eafdSMike Gerdts 249*bc36eafdSMike Gerdts DbgPrint (ASL_DEBUG_OUTPUT, 250*bc36eafdSMike Gerdts "IntegerEval: (%8.8X%8.8X %s %8.8X%8.8X) = %8.8X%8.8X\n", 251*bc36eafdSMike Gerdts ACPI_FORMAT_UINT64 (LeftValue), 252*bc36eafdSMike Gerdts DtGetOpName (Operator), 253*bc36eafdSMike Gerdts ACPI_FORMAT_UINT64 (RightValue), 254*bc36eafdSMike Gerdts ACPI_FORMAT_UINT64 (Result)); 255*bc36eafdSMike Gerdts 256*bc36eafdSMike Gerdts return (Result); 257*bc36eafdSMike Gerdts } 258*bc36eafdSMike Gerdts 259*bc36eafdSMike Gerdts 260*bc36eafdSMike Gerdts /****************************************************************************** 261*bc36eafdSMike Gerdts * 262*bc36eafdSMike Gerdts * FUNCTION: DtResolveLabel 263*bc36eafdSMike Gerdts * 264*bc36eafdSMike Gerdts * PARAMETERS: LabelString - Contains the label 265*bc36eafdSMike Gerdts * 266*bc36eafdSMike Gerdts * RETURN: Table offset associated with the label 267*bc36eafdSMike Gerdts * 268*bc36eafdSMike Gerdts * DESCRIPTION: Lookup a lable and return its value. 269*bc36eafdSMike Gerdts * 270*bc36eafdSMike Gerdts *****************************************************************************/ 271*bc36eafdSMike Gerdts 272*bc36eafdSMike Gerdts UINT64 273*bc36eafdSMike Gerdts DtResolveLabel ( 274*bc36eafdSMike Gerdts char *LabelString) 275*bc36eafdSMike Gerdts { 276*bc36eafdSMike Gerdts DT_FIELD *LabelField; 277*bc36eafdSMike Gerdts 278*bc36eafdSMike Gerdts 279*bc36eafdSMike Gerdts DbgPrint (ASL_DEBUG_OUTPUT, "Resolve Label: %s\n", LabelString); 280*bc36eafdSMike Gerdts 281*bc36eafdSMike Gerdts /* Resolve a label reference to an integer (table offset) */ 282*bc36eafdSMike Gerdts 283*bc36eafdSMike Gerdts if (*LabelString != '$') 284*bc36eafdSMike Gerdts { 285*bc36eafdSMike Gerdts return (0); 286*bc36eafdSMike Gerdts } 287*bc36eafdSMike Gerdts 288*bc36eafdSMike Gerdts LabelField = DtLookupLabel (LabelString); 289*bc36eafdSMike Gerdts if (!LabelField) 290*bc36eafdSMike Gerdts { 291*bc36eafdSMike Gerdts DtError (ASL_ERROR, ASL_MSG_UNKNOWN_LABEL, 292*bc36eafdSMike Gerdts Gbl_CurrentField, LabelString); 293*bc36eafdSMike Gerdts return (0); 294*bc36eafdSMike Gerdts } 295*bc36eafdSMike Gerdts 296*bc36eafdSMike Gerdts /* All we need from the label is the offset in the table */ 297*bc36eafdSMike Gerdts 298*bc36eafdSMike Gerdts DbgPrint (ASL_DEBUG_OUTPUT, "Resolved Label: 0x%8.8X\n", 299*bc36eafdSMike Gerdts LabelField->TableOffset); 300*bc36eafdSMike Gerdts 301*bc36eafdSMike Gerdts return (LabelField->TableOffset); 302*bc36eafdSMike Gerdts } 303*bc36eafdSMike Gerdts 304*bc36eafdSMike Gerdts 305*bc36eafdSMike Gerdts /****************************************************************************** 306*bc36eafdSMike Gerdts * 307*bc36eafdSMike Gerdts * FUNCTION: DtDetectAllLabels 308*bc36eafdSMike Gerdts * 309*bc36eafdSMike Gerdts * PARAMETERS: FieldList - Field object at start of generic list 310*bc36eafdSMike Gerdts * 311*bc36eafdSMike Gerdts * RETURN: None 312*bc36eafdSMike Gerdts * 313*bc36eafdSMike Gerdts * DESCRIPTION: Detect all labels in a list of "generic" opcodes (such as 314*bc36eafdSMike Gerdts * a UEFI table.) and insert them into the global label list. 315*bc36eafdSMike Gerdts * 316*bc36eafdSMike Gerdts *****************************************************************************/ 317*bc36eafdSMike Gerdts 318*bc36eafdSMike Gerdts void 319*bc36eafdSMike Gerdts DtDetectAllLabels ( 320*bc36eafdSMike Gerdts DT_FIELD *FieldList) 321*bc36eafdSMike Gerdts { 322*bc36eafdSMike Gerdts ACPI_DMTABLE_INFO *Info; 323*bc36eafdSMike Gerdts DT_FIELD *GenericField; 324*bc36eafdSMike Gerdts UINT32 TableOffset; 325*bc36eafdSMike Gerdts 326*bc36eafdSMike Gerdts 327*bc36eafdSMike Gerdts TableOffset = Gbl_CurrentTableOffset; 328*bc36eafdSMike Gerdts GenericField = FieldList; 329*bc36eafdSMike Gerdts 330*bc36eafdSMike Gerdts /* 331*bc36eafdSMike Gerdts * Process all "Label:" fields within the parse tree. We need 332*bc36eafdSMike Gerdts * to know the offsets for all labels before we can compile 333*bc36eafdSMike Gerdts * the parse tree in order to handle forward references. Traverse 334*bc36eafdSMike Gerdts * tree and get/set all field lengths of all operators in order to 335*bc36eafdSMike Gerdts * determine the label offsets. 336*bc36eafdSMike Gerdts */ 337*bc36eafdSMike Gerdts while (GenericField) 338*bc36eafdSMike Gerdts { 339*bc36eafdSMike Gerdts Info = DtGetGenericTableInfo (GenericField->Name); 340*bc36eafdSMike Gerdts if (Info) 341*bc36eafdSMike Gerdts { 342*bc36eafdSMike Gerdts /* Maintain table offsets */ 343*bc36eafdSMike Gerdts 344*bc36eafdSMike Gerdts GenericField->TableOffset = TableOffset; 345*bc36eafdSMike Gerdts TableOffset += DtGetFieldLength (GenericField, Info); 346*bc36eafdSMike Gerdts 347*bc36eafdSMike Gerdts /* Insert all labels in the global label list */ 348*bc36eafdSMike Gerdts 349*bc36eafdSMike Gerdts if (Info->Opcode == ACPI_DMT_LABEL) 350*bc36eafdSMike Gerdts { 351*bc36eafdSMike Gerdts DtInsertLabelField (GenericField); 352*bc36eafdSMike Gerdts } 353*bc36eafdSMike Gerdts } 354*bc36eafdSMike Gerdts 355*bc36eafdSMike Gerdts GenericField = GenericField->Next; 356*bc36eafdSMike Gerdts } 357*bc36eafdSMike Gerdts } 358*bc36eafdSMike Gerdts 359*bc36eafdSMike Gerdts 360*bc36eafdSMike Gerdts /****************************************************************************** 361*bc36eafdSMike Gerdts * 362*bc36eafdSMike Gerdts * FUNCTION: DtInsertLabelField 363*bc36eafdSMike Gerdts * 364*bc36eafdSMike Gerdts * PARAMETERS: Field - Field object with Label to be inserted 365*bc36eafdSMike Gerdts * 366*bc36eafdSMike Gerdts * RETURN: None 367*bc36eafdSMike Gerdts * 368*bc36eafdSMike Gerdts * DESCRIPTION: Insert a label field into the global label list 369*bc36eafdSMike Gerdts * 370*bc36eafdSMike Gerdts *****************************************************************************/ 371*bc36eafdSMike Gerdts 372*bc36eafdSMike Gerdts static void 373*bc36eafdSMike Gerdts DtInsertLabelField ( 374*bc36eafdSMike Gerdts DT_FIELD *Field) 375*bc36eafdSMike Gerdts { 376*bc36eafdSMike Gerdts 377*bc36eafdSMike Gerdts DbgPrint (ASL_DEBUG_OUTPUT, 378*bc36eafdSMike Gerdts "DtInsertLabelField: Found Label : %s at output table offset %X\n", 379*bc36eafdSMike Gerdts Field->Value, Field->TableOffset); 380*bc36eafdSMike Gerdts 381*bc36eafdSMike Gerdts Field->NextLabel = Gbl_LabelList; 382*bc36eafdSMike Gerdts Gbl_LabelList = Field; 383*bc36eafdSMike Gerdts } 384*bc36eafdSMike Gerdts 385*bc36eafdSMike Gerdts 386*bc36eafdSMike Gerdts /****************************************************************************** 387*bc36eafdSMike Gerdts * 388*bc36eafdSMike Gerdts * FUNCTION: DtLookupLabel 389*bc36eafdSMike Gerdts * 390*bc36eafdSMike Gerdts * PARAMETERS: Name - Label to be resolved 391*bc36eafdSMike Gerdts * 392*bc36eafdSMike Gerdts * RETURN: Field object associated with the label 393*bc36eafdSMike Gerdts * 394*bc36eafdSMike Gerdts * DESCRIPTION: Lookup a label in the global label list. Used during the 395*bc36eafdSMike Gerdts * resolution of integer expressions. 396*bc36eafdSMike Gerdts * 397*bc36eafdSMike Gerdts *****************************************************************************/ 398*bc36eafdSMike Gerdts 399*bc36eafdSMike Gerdts static DT_FIELD * 400*bc36eafdSMike Gerdts DtLookupLabel ( 401*bc36eafdSMike Gerdts char *Name) 402*bc36eafdSMike Gerdts { 403*bc36eafdSMike Gerdts DT_FIELD *LabelField; 404*bc36eafdSMike Gerdts 405*bc36eafdSMike Gerdts 406*bc36eafdSMike Gerdts /* Skip a leading $ */ 407*bc36eafdSMike Gerdts 408*bc36eafdSMike Gerdts if (*Name == '$') 409*bc36eafdSMike Gerdts { 410*bc36eafdSMike Gerdts Name++; 411*bc36eafdSMike Gerdts } 412*bc36eafdSMike Gerdts 413*bc36eafdSMike Gerdts /* Search global list */ 414*bc36eafdSMike Gerdts 415*bc36eafdSMike Gerdts LabelField = Gbl_LabelList; 416*bc36eafdSMike Gerdts while (LabelField) 417*bc36eafdSMike Gerdts { 418*bc36eafdSMike Gerdts if (!strcmp (Name, LabelField->Value)) 419*bc36eafdSMike Gerdts { 420*bc36eafdSMike Gerdts return (LabelField); 421*bc36eafdSMike Gerdts } 422*bc36eafdSMike Gerdts 423*bc36eafdSMike Gerdts LabelField = LabelField->NextLabel; 424*bc36eafdSMike Gerdts } 425*bc36eafdSMike Gerdts 426*bc36eafdSMike Gerdts return (NULL); 427*bc36eafdSMike Gerdts } 428