update list of C math functions
[ghc-hetmet.git] / compiler / cmm / CLabel.hs
1 {-# OPTIONS -w #-}
2 -- The above warning supression flag is a temporary kludge.
3 -- While working on this module you are encouraged to remove it and fix
4 -- any warnings in the module. See
5 --     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
6 -- for details
7
8 -----------------------------------------------------------------------------
9 --
10 -- Object-file symbols (called CLabel for histerical raisins).
11 --
12 -- (c) The University of Glasgow 2004-2006
13 --
14 -----------------------------------------------------------------------------
15
16 module CLabel (
17         CLabel, -- abstract type
18
19         mkClosureLabel,
20         mkSRTLabel,
21         mkInfoTableLabel,
22         mkEntryLabel,
23         mkSlowEntryLabel,
24         mkConEntryLabel,
25         mkStaticConEntryLabel,
26         mkRednCountsLabel,
27         mkConInfoTableLabel,
28         mkStaticInfoTableLabel,
29         mkLargeSRTLabel,
30         mkApEntryLabel,
31         mkApInfoTableLabel,
32         mkClosureTableLabel,
33
34         mkLocalClosureLabel,
35         mkLocalInfoTableLabel,
36         mkLocalEntryLabel,
37         mkLocalConEntryLabel,
38         mkLocalStaticConEntryLabel,
39         mkLocalConInfoTableLabel,
40         mkLocalStaticInfoTableLabel,
41         mkLocalClosureTableLabel,
42
43         mkReturnPtLabel,
44         mkReturnInfoLabel,
45         mkAltLabel,
46         mkDefaultLabel,
47         mkBitmapLabel,
48         mkStringLitLabel,
49
50         mkAsmTempLabel,
51
52         mkModuleInitLabel,
53         mkPlainModuleInitLabel,
54         mkModuleInitTableLabel,
55
56         mkSplitMarkerLabel,
57         mkDirty_MUT_VAR_Label,
58         mkUpdInfoLabel,
59         mkIndStaticInfoLabel,
60         mkMainCapabilityLabel,
61         mkMAP_FROZEN_infoLabel,
62         mkMAP_DIRTY_infoLabel,
63         mkEMPTY_MVAR_infoLabel,
64
65         mkTopTickyCtrLabel,
66         mkCAFBlackHoleInfoTableLabel,
67         mkRtsPrimOpLabel,
68         mkRtsSlowTickyCtrLabel,
69
70         moduleRegdLabel,
71         moduleRegTableLabel,
72
73         mkSelectorInfoLabel,
74         mkSelectorEntryLabel,
75
76         mkRtsInfoLabel,
77         mkRtsEntryLabel,
78         mkRtsRetInfoLabel,
79         mkRtsRetLabel,
80         mkRtsCodeLabel,
81         mkRtsDataLabel,
82         mkRtsGcPtrLabel,
83
84         mkRtsInfoLabelFS,
85         mkRtsEntryLabelFS,
86         mkRtsRetInfoLabelFS,
87         mkRtsRetLabelFS,
88         mkRtsCodeLabelFS,
89         mkRtsDataLabelFS,
90
91         mkRtsApFastLabel,
92
93         mkForeignLabel,
94         addLabelSize,
95         foreignLabelStdcallInfo,
96
97         mkCCLabel, mkCCSLabel,
98
99         DynamicLinkerLabelInfo(..),
100         mkDynamicLinkerLabel,
101         dynamicLinkerLabelInfo,
102         
103         mkPicBaseLabel,
104         mkDeadStripPreventer,
105
106         mkHpcTicksLabel,
107         mkHpcModuleNameLabel,
108
109         hasCAF,
110         infoLblToEntryLbl, entryLblToInfoLbl, cvtToClosureLbl, cvtToSRTLbl,
111         needsCDecl, isAsmTemp, maybeAsmTemp, externallyVisibleCLabel,
112         isMathFun,
113         isCFunctionLabel, isGcPtrLabel, labelDynamic,
114
115         pprCLabel
116     ) where
117
118 #include "HsVersions.h"
119
120 import IdInfo
121 import StaticFlags
122 import BasicTypes
123 import Literal
124 import Packages
125 import DataCon
126 import PackageConfig
127 import Module
128 import Name
129 import Unique
130 import PrimOp
131 import Config
132 import CostCentre
133 import Outputable
134 import FastString
135 import DynFlags
136
137 -- -----------------------------------------------------------------------------
138 -- The CLabel type
139
140 {-
141 CLabel is an abstract type that supports the following operations:
142
143   - Pretty printing
144
145   - In a C file, does it need to be declared before use?  (i.e. is it
146     guaranteed to be already in scope in the places we need to refer to it?)
147
148   - If it needs to be declared, what type (code or data) should it be
149     declared to have?
150
151   - Is it visible outside this object file or not?
152
153   - Is it "dynamic" (see details below)
154
155   - Eq and Ord, so that we can make sets of CLabels (currently only
156     used in outputting C as far as I can tell, to avoid generating
157     more than one declaration for any given label).
158
159   - Converting an info table label into an entry label.
160 -}
161
162 data CLabel
163   = IdLabel                     -- A family of labels related to the
164         Name                    -- definition of a particular Id or Con
165         CafInfo
166         IdLabelInfo
167
168   | CaseLabel                   -- A family of labels related to a particular
169                                 -- case expression.
170         {-# UNPACK #-} !Unique  -- Unique says which case expression
171         CaseLabelInfo
172
173   | AsmTempLabel 
174         {-# UNPACK #-} !Unique
175
176   | StringLitLabel
177         {-# UNPACK #-} !Unique
178
179   | ModuleInitLabel 
180         Module                  -- the module name
181         String                  -- its "way"
182         -- at some point we might want some kind of version number in
183         -- the module init label, to guard against compiling modules in
184         -- the wrong order.  We can't use the interface file version however,
185         -- because we don't always recompile modules which depend on a module
186         -- whose version has changed.
187
188   | PlainModuleInitLabel        -- without the version & way info
189         Module
190
191   | ModuleInitTableLabel        -- table of imported modules to init
192         Module
193
194   | ModuleRegdLabel
195
196   | RtsLabel RtsLabelInfo
197
198   | ForeignLabel FastString     -- a 'C' (or otherwise foreign) label
199         (Maybe Int)             -- possible '@n' suffix for stdcall functions
200                 -- When generating C, the '@n' suffix is omitted, but when
201                 -- generating assembler we must add it to the label.
202         Bool                    -- True <=> is dynamic
203         FunctionOrData
204
205   | CC_Label  CostCentre
206   | CCS_Label CostCentreStack
207
208       -- Dynamic Linking in the NCG:
209       -- generated and used inside the NCG only,
210       -- see module PositionIndependentCode for details.
211       
212   | DynamicLinkerLabel DynamicLinkerLabelInfo CLabel
213         -- special variants of a label used for dynamic linking
214
215   | PicBaseLabel                -- a label used as a base for PIC calculations
216                                 -- on some platforms.
217                                 -- It takes the form of a local numeric
218                                 -- assembler label '1'; it is pretty-printed
219                                 -- as 1b, referring to the previous definition
220                                 -- of 1: in the assembler source file.
221
222   | DeadStripPreventer CLabel
223     -- label before an info table to prevent excessive dead-stripping on darwin
224
225   | HpcTicksLabel Module       -- Per-module table of tick locations
226   | HpcModuleNameLabel         -- Per-module name of the module for Hpc
227
228   | LargeSRTLabel           -- Label of an StgLargeSRT
229         {-# UNPACK #-} !Unique
230
231   | LargeBitmapLabel        -- A bitmap (function or case return)
232         {-# UNPACK #-} !Unique
233
234   deriving (Eq, Ord)
235
236 data IdLabelInfo
237   = Closure             -- Label for closure
238   | SRT                 -- Static reference table
239   | InfoTable           -- Info tables for closures; always read-only
240   | Entry               -- entry point
241   | Slow                -- slow entry point
242
243   | RednCounts          -- Label of place to keep Ticky-ticky  info for 
244                         -- this Id
245
246   | ConEntry            -- constructor entry point
247   | ConInfoTable                -- corresponding info table
248   | StaticConEntry      -- static constructor entry point
249   | StaticInfoTable     -- corresponding info table
250
251   | ClosureTable        -- table of closures for Enum tycons
252
253   deriving (Eq, Ord)
254
255
256 data CaseLabelInfo
257   = CaseReturnPt
258   | CaseReturnInfo
259   | CaseAlt ConTag
260   | CaseDefault
261   deriving (Eq, Ord)
262
263
264 data RtsLabelInfo
265   = RtsSelectorInfoTable Bool{-updatable-} Int{-offset-}        -- Selector thunks
266   | RtsSelectorEntry   Bool{-updatable-} Int{-offset-}
267
268   | RtsApInfoTable Bool{-updatable-} Int{-arity-}               -- AP thunks
269   | RtsApEntry   Bool{-updatable-} Int{-arity-}
270
271   | RtsPrimOp PrimOp
272
273   | RtsInfo       LitString     -- misc rts info tables
274   | RtsEntry      LitString     -- misc rts entry points
275   | RtsRetInfo    LitString     -- misc rts ret info tables
276   | RtsRet        LitString     -- misc rts return points
277   | RtsData       LitString     -- misc rts data bits
278   | RtsGcPtr      LitString     -- GcPtrs eg CHARLIKE_closure
279   | RtsCode       LitString     -- misc rts code
280
281   | RtsInfoFS     FastString    -- misc rts info tables
282   | RtsEntryFS    FastString    -- misc rts entry points
283   | RtsRetInfoFS  FastString    -- misc rts ret info tables
284   | RtsRetFS      FastString    -- misc rts return points
285   | RtsDataFS     FastString    -- misc rts data bits, eg CHARLIKE_closure
286   | RtsCodeFS     FastString    -- misc rts code
287
288   | RtsApFast   LitString       -- _fast versions of generic apply
289
290   | RtsSlowTickyCtr String
291
292   deriving (Eq, Ord)
293         -- NOTE: Eq on LitString compares the pointer only, so this isn't
294         -- a real equality.
295
296 data DynamicLinkerLabelInfo
297   = CodeStub            -- MachO: Lfoo$stub, ELF: foo@plt
298   | SymbolPtr           -- MachO: Lfoo$non_lazy_ptr, Windows: __imp_foo
299   | GotSymbolPtr        -- ELF: foo@got
300   | GotSymbolOffset     -- ELF: foo@gotoff
301   
302   deriving (Eq, Ord)
303   
304 -- -----------------------------------------------------------------------------
305 -- Constructing CLabels
306
307 -- These are always local:
308 mkSRTLabel              name c  = IdLabel name  c SRT
309 mkSlowEntryLabel        name c  = IdLabel name  c Slow
310 mkRednCountsLabel       name c  = IdLabel name  c RednCounts
311
312 -- These have local & (possibly) external variants:
313 mkLocalClosureLabel     name c  = IdLabel name  c Closure
314 mkLocalInfoTableLabel   name c  = IdLabel name  c InfoTable
315 mkLocalEntryLabel       name c  = IdLabel name  c Entry
316 mkLocalClosureTableLabel name c = IdLabel name  c ClosureTable
317
318 mkClosureLabel name         c     = IdLabel name c Closure
319 mkInfoTableLabel name       c     = IdLabel name c InfoTable
320 mkEntryLabel name           c     = IdLabel name c Entry
321 mkClosureTableLabel name    c     = IdLabel name c ClosureTable
322 mkLocalConInfoTableLabel    c con = IdLabel con c ConInfoTable
323 mkLocalConEntryLabel        c con = IdLabel con c ConEntry
324 mkLocalStaticInfoTableLabel c con = IdLabel con c StaticInfoTable
325 mkLocalStaticConEntryLabel  c con = IdLabel con c StaticConEntry
326 mkConInfoTableLabel name    c     = IdLabel    name c ConInfoTable
327 mkStaticInfoTableLabel name c     = IdLabel    name c StaticInfoTable
328
329 mkConEntryLabel name        c     = IdLabel name c ConEntry
330 mkStaticConEntryLabel name  c     = IdLabel name c StaticConEntry
331
332 mkLargeSRTLabel uniq    = LargeSRTLabel uniq
333 mkBitmapLabel   uniq    = LargeBitmapLabel uniq
334
335 mkReturnPtLabel uniq            = CaseLabel uniq CaseReturnPt
336 mkReturnInfoLabel uniq          = CaseLabel uniq CaseReturnInfo
337 mkAltLabel      uniq tag        = CaseLabel uniq (CaseAlt tag)
338 mkDefaultLabel  uniq            = CaseLabel uniq CaseDefault
339
340 mkStringLitLabel                = StringLitLabel
341 mkAsmTempLabel :: Uniquable a => a -> CLabel
342 mkAsmTempLabel a                = AsmTempLabel (getUnique a)
343
344 mkModuleInitLabel :: Module -> String -> CLabel
345 mkModuleInitLabel mod way        = ModuleInitLabel mod way
346
347 mkPlainModuleInitLabel :: Module -> CLabel
348 mkPlainModuleInitLabel mod       = PlainModuleInitLabel mod
349
350 mkModuleInitTableLabel :: Module -> CLabel
351 mkModuleInitTableLabel mod       = ModuleInitTableLabel mod
352
353         -- Some fixed runtime system labels
354
355 mkSplitMarkerLabel              = RtsLabel (RtsCode (sLit "__stg_split_marker"))
356 mkDirty_MUT_VAR_Label           = RtsLabel (RtsCode (sLit "dirty_MUT_VAR"))
357 mkUpdInfoLabel                  = RtsLabel (RtsInfo (sLit "stg_upd_frame"))
358 mkIndStaticInfoLabel            = RtsLabel (RtsInfo (sLit "stg_IND_STATIC"))
359 mkMainCapabilityLabel           = RtsLabel (RtsData (sLit "MainCapability"))
360 mkMAP_FROZEN_infoLabel          = RtsLabel (RtsInfo (sLit "stg_MUT_ARR_PTRS_FROZEN0"))
361 mkMAP_DIRTY_infoLabel           = RtsLabel (RtsInfo (sLit "stg_MUT_ARR_PTRS_DIRTY"))
362 mkEMPTY_MVAR_infoLabel          = RtsLabel (RtsInfo (sLit "stg_EMPTY_MVAR"))
363
364 mkTopTickyCtrLabel              = RtsLabel (RtsData (sLit "top_ct"))
365 mkCAFBlackHoleInfoTableLabel    = RtsLabel (RtsInfo (sLit "stg_CAF_BLACKHOLE"))
366 mkRtsPrimOpLabel primop         = RtsLabel (RtsPrimOp primop)
367
368 moduleRegdLabel                 = ModuleRegdLabel
369 moduleRegTableLabel             = ModuleInitTableLabel  
370
371 mkSelectorInfoLabel  upd off    = RtsLabel (RtsSelectorInfoTable upd off)
372 mkSelectorEntryLabel upd off    = RtsLabel (RtsSelectorEntry   upd off)
373
374 mkApInfoTableLabel  upd off     = RtsLabel (RtsApInfoTable upd off)
375 mkApEntryLabel upd off          = RtsLabel (RtsApEntry   upd off)
376
377         -- Foreign labels
378
379 mkForeignLabel :: FastString -> Maybe Int -> Bool -> FunctionOrData -> CLabel
380 mkForeignLabel str mb_sz is_dynamic fod
381     = ForeignLabel str mb_sz is_dynamic fod
382
383 addLabelSize :: CLabel -> Int -> CLabel
384 addLabelSize (ForeignLabel str _ is_dynamic fod) sz
385   = ForeignLabel str (Just sz) is_dynamic fod
386 addLabelSize label _
387   = label
388
389 foreignLabelStdcallInfo :: CLabel -> Maybe Int
390 foreignLabelStdcallInfo (ForeignLabel _ info _ _) = info
391 foreignLabelStdcallInfo _lbl = Nothing
392
393         -- Cost centres etc.
394
395 mkCCLabel       cc              = CC_Label cc
396 mkCCSLabel      ccs             = CCS_Label ccs
397
398 mkRtsInfoLabel      str = RtsLabel (RtsInfo      str)
399 mkRtsEntryLabel     str = RtsLabel (RtsEntry     str)
400 mkRtsRetInfoLabel   str = RtsLabel (RtsRetInfo   str)
401 mkRtsRetLabel       str = RtsLabel (RtsRet       str)
402 mkRtsCodeLabel      str = RtsLabel (RtsCode      str)
403 mkRtsDataLabel      str = RtsLabel (RtsData      str)
404 mkRtsGcPtrLabel     str = RtsLabel (RtsGcPtr     str)
405
406 mkRtsInfoLabelFS    str = RtsLabel (RtsInfoFS    str)
407 mkRtsEntryLabelFS   str = RtsLabel (RtsEntryFS   str)
408 mkRtsRetInfoLabelFS str = RtsLabel (RtsRetInfoFS str)
409 mkRtsRetLabelFS     str = RtsLabel (RtsRetFS     str)
410 mkRtsCodeLabelFS    str = RtsLabel (RtsCodeFS    str)
411 mkRtsDataLabelFS    str = RtsLabel (RtsDataFS    str)
412
413 mkRtsApFastLabel str = RtsLabel (RtsApFast str)
414
415 mkRtsSlowTickyCtrLabel :: String -> CLabel
416 mkRtsSlowTickyCtrLabel pat = RtsLabel (RtsSlowTickyCtr pat)
417
418         -- Coverage
419
420 mkHpcTicksLabel                = HpcTicksLabel
421 mkHpcModuleNameLabel           = HpcModuleNameLabel
422
423         -- Dynamic linking
424         
425 mkDynamicLinkerLabel :: DynamicLinkerLabelInfo -> CLabel -> CLabel
426 mkDynamicLinkerLabel = DynamicLinkerLabel
427
428 dynamicLinkerLabelInfo :: CLabel -> Maybe (DynamicLinkerLabelInfo, CLabel)
429 dynamicLinkerLabelInfo (DynamicLinkerLabel info lbl) = Just (info, lbl)
430 dynamicLinkerLabelInfo _ = Nothing
431
432         -- Position independent code
433         
434 mkPicBaseLabel :: CLabel
435 mkPicBaseLabel = PicBaseLabel
436
437 mkDeadStripPreventer :: CLabel -> CLabel
438 mkDeadStripPreventer lbl = DeadStripPreventer lbl
439
440 -- -----------------------------------------------------------------------------
441 -- Converting between info labels and entry/ret labels.
442
443 infoLblToEntryLbl :: CLabel -> CLabel 
444 infoLblToEntryLbl (IdLabel n c InfoTable) = IdLabel n c Entry
445 infoLblToEntryLbl (IdLabel n c ConInfoTable) = IdLabel n c ConEntry
446 infoLblToEntryLbl (IdLabel n c StaticInfoTable) = IdLabel n c StaticConEntry
447 infoLblToEntryLbl (CaseLabel n CaseReturnInfo) = CaseLabel n CaseReturnPt
448 infoLblToEntryLbl (RtsLabel (RtsInfo s)) = RtsLabel (RtsEntry s)
449 infoLblToEntryLbl (RtsLabel (RtsRetInfo s)) = RtsLabel (RtsRet s)
450 infoLblToEntryLbl (RtsLabel (RtsInfoFS s)) = RtsLabel (RtsEntryFS s)
451 infoLblToEntryLbl (RtsLabel (RtsRetInfoFS s)) = RtsLabel (RtsRetFS s)
452 infoLblToEntryLbl _ = panic "CLabel.infoLblToEntryLbl"
453
454 entryLblToInfoLbl :: CLabel -> CLabel 
455 entryLblToInfoLbl (IdLabel n c Entry) = IdLabel n c InfoTable
456 entryLblToInfoLbl (IdLabel n c ConEntry) = IdLabel n c ConInfoTable
457 entryLblToInfoLbl (IdLabel n c StaticConEntry) = IdLabel n c StaticInfoTable
458 entryLblToInfoLbl (CaseLabel n CaseReturnPt) = CaseLabel n CaseReturnInfo
459 entryLblToInfoLbl (RtsLabel (RtsEntry s)) = RtsLabel (RtsInfo s)
460 entryLblToInfoLbl (RtsLabel (RtsRet s)) = RtsLabel (RtsRetInfo s)
461 entryLblToInfoLbl (RtsLabel (RtsEntryFS s)) = RtsLabel (RtsInfoFS s)
462 entryLblToInfoLbl (RtsLabel (RtsRetFS s)) = RtsLabel (RtsRetInfoFS s)
463 entryLblToInfoLbl l = pprPanic "CLabel.entryLblToInfoLbl" (pprCLabel l)
464
465 cvtToClosureLbl   (IdLabel n c InfoTable) = IdLabel n c Closure
466 cvtToClosureLbl   (IdLabel n c Entry)     = IdLabel n c Closure
467 cvtToClosureLbl   (IdLabel n c ConEntry)  = IdLabel n c Closure
468 cvtToClosureLbl l@(IdLabel n c Closure)   = l
469 cvtToClosureLbl l = pprPanic "cvtToClosureLbl" (pprCLabel l)
470
471 cvtToSRTLbl   (IdLabel n c InfoTable) = mkSRTLabel n c
472 cvtToSRTLbl   (IdLabel n c Entry)     = mkSRTLabel n c
473 cvtToSRTLbl   (IdLabel n c ConEntry)  = mkSRTLabel n c
474 cvtToSRTLbl l@(IdLabel n c Closure)   = mkSRTLabel n c
475 cvtToSRTLbl l = pprPanic "cvtToSRTLbl" (pprCLabel l)
476
477 -- -----------------------------------------------------------------------------
478 -- Does a CLabel refer to a CAF?
479 hasCAF :: CLabel -> Bool
480 hasCAF (IdLabel _ MayHaveCafRefs _) = True
481 hasCAF _                            = False
482
483 -- -----------------------------------------------------------------------------
484 -- Does a CLabel need declaring before use or not?
485 --
486 -- See wiki:Commentary/Compiler/Backends/PprC#Prototypes
487
488 needsCDecl :: CLabel -> Bool
489   -- False <=> it's pre-declared; don't bother
490   -- don't bother declaring SRT & Bitmap labels, we always make sure
491   -- they are defined before use.
492 needsCDecl (IdLabel _ _ SRT)            = False
493 needsCDecl (LargeSRTLabel _)            = False
494 needsCDecl (LargeBitmapLabel _)         = False
495 needsCDecl (IdLabel _ _ _)              = True
496 needsCDecl (CaseLabel _ _)              = True
497 needsCDecl (ModuleInitLabel _ _)        = True
498 needsCDecl (PlainModuleInitLabel _)     = True
499 needsCDecl (ModuleInitTableLabel _)     = True
500 needsCDecl ModuleRegdLabel              = False
501
502 needsCDecl (StringLitLabel _)           = False
503 needsCDecl (AsmTempLabel _)             = False
504 needsCDecl (RtsLabel _)                 = False
505 needsCDecl l@(ForeignLabel _ _ _ _)     = not (isMathFun l)
506 needsCDecl (CC_Label _)                 = True
507 needsCDecl (CCS_Label _)                = True
508 needsCDecl (HpcTicksLabel _)            = True
509 needsCDecl HpcModuleNameLabel           = False
510
511 -- Whether the label is an assembler temporary:
512
513 isAsmTemp  :: CLabel -> Bool    -- is a local temporary for native code generation
514 isAsmTemp (AsmTempLabel _) = True
515 isAsmTemp _                = False
516
517 maybeAsmTemp :: CLabel -> Maybe Unique
518 maybeAsmTemp (AsmTempLabel uq) = Just uq
519 maybeAsmTemp _                 = Nothing
520
521 -- some labels have C prototypes in scope when compiling via C, because
522 -- they are builtin to the C compiler.  For these labels we avoid
523 -- generating our own C prototypes.
524 isMathFun :: CLabel -> Bool
525 isMathFun (ForeignLabel fs _ _ _) = fs `elem` math_funs
526   where
527   math_funs = [
528         -- _ISOC99_SOURCE
529         (fsLit "acos"),         (fsLit "acosf"),        (fsLit "acosh"),
530         (fsLit "acoshf"),       (fsLit "acoshl"),       (fsLit "acosl"),
531         (fsLit "asin"),         (fsLit "asinf"),        (fsLit "asinl"),
532         (fsLit "asinh"),        (fsLit "asinhf"),       (fsLit "asinhl"),
533         (fsLit "atan"),         (fsLit "atanf"),        (fsLit "atanl"),
534         (fsLit "atan2"),        (fsLit "atan2f"),       (fsLit "atan2l"),
535         (fsLit "atanh"),        (fsLit "atanhf"),       (fsLit "atanhl"),
536         (fsLit "cbrt"),         (fsLit "cbrtf"),        (fsLit "cbrtl"),
537         (fsLit "ceil"),         (fsLit "ceilf"),        (fsLit "ceill"),
538         (fsLit "copysign"),     (fsLit "copysignf"),    (fsLit "copysignl"),
539         (fsLit "cos"),          (fsLit "cosf"),         (fsLit "cosl"),
540         (fsLit "cosh"),         (fsLit "coshf"),        (fsLit "coshl"),
541         (fsLit "erf"),          (fsLit "erff"),         (fsLit "erfl"),
542         (fsLit "erfc"),         (fsLit "erfcf"),        (fsLit "erfcl"),
543         (fsLit "exp"),          (fsLit "expf"),         (fsLit "expl"),
544         (fsLit "exp2"),         (fsLit "exp2f"),        (fsLit "exp2l"),
545         (fsLit "expm1"),        (fsLit "expm1f"),       (fsLit "expm1l"),
546         (fsLit "fabs"),         (fsLit "fabsf"),        (fsLit "fabsl"),
547         (fsLit "fdim"),         (fsLit "fdimf"),        (fsLit "fdiml"),
548         (fsLit "floor"),        (fsLit "floorf"),       (fsLit "floorl"),
549         (fsLit "fma"),          (fsLit "fmaf"),         (fsLit "fmal"),
550         (fsLit "fmax"),         (fsLit "fmaxf"),        (fsLit "fmaxl"),
551         (fsLit "fmin"),         (fsLit "fminf"),        (fsLit "fminl"),
552         (fsLit "fmod"),         (fsLit "fmodf"),        (fsLit "fmodl"),
553         (fsLit "frexp"),        (fsLit "frexpf"),       (fsLit "frexpl"),
554         (fsLit "hypot"),        (fsLit "hypotf"),       (fsLit "hypotl"),
555         (fsLit "ilogb"),        (fsLit "ilogbf"),       (fsLit "ilogbl"),
556         (fsLit "ldexp"),        (fsLit "ldexpf"),       (fsLit "ldexpl"),
557         (fsLit "lgamma"),       (fsLit "lgammaf"),      (fsLit "lgammal"),
558         (fsLit "llrint"),       (fsLit "llrintf"),      (fsLit "llrintl"),
559         (fsLit "llround"),      (fsLit "llroundf"),     (fsLit "llroundl"),
560         (fsLit "log"),          (fsLit "logf"),         (fsLit "logl"),
561         (fsLit "log10l"),       (fsLit "log10"),        (fsLit "log10f"),
562         (fsLit "log1pl"),       (fsLit "log1p"),        (fsLit "log1pf"),
563         (fsLit "log2"),         (fsLit "log2f"),        (fsLit "log2l"),
564         (fsLit "logb"),         (fsLit "logbf"),        (fsLit "logbl"),
565         (fsLit "lrint"),        (fsLit "lrintf"),       (fsLit "lrintl"),
566         (fsLit "lround"),       (fsLit "lroundf"),      (fsLit "lroundl"),
567         (fsLit "modf"),         (fsLit "modff"),        (fsLit "modfl"),
568         (fsLit "nan"),          (fsLit "nanf"),         (fsLit "nanl"),
569         (fsLit "nearbyint"),    (fsLit "nearbyintf"),   (fsLit "nearbyintl"),
570         (fsLit "nextafter"),    (fsLit "nextafterf"),   (fsLit "nextafterl"),
571         (fsLit "nexttoward"),   (fsLit "nexttowardf"),  (fsLit "nexttowardl"),
572         (fsLit "pow"),          (fsLit "powf"),         (fsLit "powl"),
573         (fsLit "remainder"),    (fsLit "remainderf"),   (fsLit "remainderl"),
574         (fsLit "remquo"),       (fsLit "remquof"),      (fsLit "remquol"),
575         (fsLit "rint"),         (fsLit "rintf"),        (fsLit "rintl"),
576         (fsLit "round"),        (fsLit "roundf"),       (fsLit "roundl"),
577         (fsLit "scalbln"),      (fsLit "scalblnf"),     (fsLit "scalblnl"),
578         (fsLit "scalbn"),       (fsLit "scalbnf"),      (fsLit "scalbnl"),
579         (fsLit "sin"),          (fsLit "sinf"),         (fsLit "sinl"),
580         (fsLit "sinh"),         (fsLit "sinhf"),        (fsLit "sinhl"),
581         (fsLit "sqrt"),         (fsLit "sqrtf"),        (fsLit "sqrtl"),
582         (fsLit "tan"),          (fsLit "tanf"),         (fsLit "tanl"),
583         (fsLit "tanh"),         (fsLit "tanhf"),        (fsLit "tanhl"),
584         (fsLit "tgamma"),       (fsLit "tgammaf"),      (fsLit "tgammal"),
585         (fsLit "trunc"),        (fsLit "truncf"),       (fsLit "truncl"),
586         -- ISO C 99 also defines these function-like macros in math.h:
587         -- fpclassify, isfinite, isinf, isnormal, signbit, isgreater,
588         -- isgreaterequal, isless, islessequal, islessgreater, isunordered
589
590         -- additional symbols from _BSD_SOURCE
591         (fsLit "drem"),         (fsLit "dremf"),        (fsLit "dreml"),
592         (fsLit "finite"),       (fsLit "finitef"),      (fsLit "finitel"),
593         (fsLit "gamma"),        (fsLit "gammaf"),       (fsLit "gammal"),
594         (fsLit "isinf"),        (fsLit "isinff"),       (fsLit "isinfl"),
595         (fsLit "isnan"),        (fsLit "isnanf"),       (fsLit "isnanl"),
596         (fsLit "j0"),           (fsLit "j0f"),          (fsLit "j0l"),
597         (fsLit "j1"),           (fsLit "j1f"),          (fsLit "j1l"),
598         (fsLit "jn"),           (fsLit "jnf"),          (fsLit "jnl"),
599         (fsLit "lgamma_r"),     (fsLit "lgammaf_r"),    (fsLit "lgammal_r"),
600         (fsLit "scalb"),        (fsLit "scalbf"),       (fsLit "scalbl"),
601         (fsLit "significand"),  (fsLit "significandf"), (fsLit "significandl"),
602         (fsLit "y0"),           (fsLit "y0f"),          (fsLit "y0l"),
603         (fsLit "y1"),           (fsLit "y1f"),          (fsLit "y1l"),
604         (fsLit "yn"),           (fsLit "ynf"),          (fsLit "ynl")
605     ]
606 isMathFun _ = False
607
608 -- -----------------------------------------------------------------------------
609 -- Is a CLabel visible outside this object file or not?
610
611 -- From the point of view of the code generator, a name is
612 -- externally visible if it has to be declared as exported
613 -- in the .o file's symbol table; that is, made non-static.
614
615 externallyVisibleCLabel :: CLabel -> Bool -- not C "static"
616 externallyVisibleCLabel (CaseLabel _ _)    = False
617 externallyVisibleCLabel (StringLitLabel _) = False
618 externallyVisibleCLabel (AsmTempLabel _)   = False
619 externallyVisibleCLabel (ModuleInitLabel _ _) = True
620 externallyVisibleCLabel (PlainModuleInitLabel _)= True
621 externallyVisibleCLabel (ModuleInitTableLabel _)= False
622 externallyVisibleCLabel ModuleRegdLabel    = False
623 externallyVisibleCLabel (RtsLabel _)       = True
624 externallyVisibleCLabel (ForeignLabel _ _ _ _) = True
625 externallyVisibleCLabel (IdLabel name _ _)     = isExternalName name
626 externallyVisibleCLabel (CC_Label _)       = True
627 externallyVisibleCLabel (CCS_Label _)      = True
628 externallyVisibleCLabel (DynamicLinkerLabel _ _)  = False
629 externallyVisibleCLabel (HpcTicksLabel _)   = True
630 externallyVisibleCLabel HpcModuleNameLabel      = False
631 externallyVisibleCLabel (LargeBitmapLabel _) = False
632 externallyVisibleCLabel (LargeSRTLabel _) = False
633
634 -- -----------------------------------------------------------------------------
635 -- Finding the "type" of a CLabel 
636
637 -- For generating correct types in label declarations:
638
639 data CLabelType
640   = CodeLabel   -- Address of some executable instructions
641   | DataLabel   -- Address of data, not a GC ptr
642   | GcPtrLabel  -- Address of a (presumably static) GC object
643
644 isCFunctionLabel :: CLabel -> Bool
645 isCFunctionLabel lbl = case labelType lbl of
646                         CodeLabel -> True
647                         _other    -> False
648
649 isGcPtrLabel :: CLabel -> Bool
650 isGcPtrLabel lbl = case labelType lbl of
651                         GcPtrLabel -> True
652                         _other     -> False
653
654 labelType :: CLabel -> CLabelType
655 labelType (RtsLabel (RtsSelectorInfoTable _ _)) = DataLabel
656 labelType (RtsLabel (RtsApInfoTable _ _))       = DataLabel
657 labelType (RtsLabel (RtsData _))              = DataLabel
658 labelType (RtsLabel (RtsGcPtr _))             = GcPtrLabel
659 labelType (RtsLabel (RtsCode _))              = CodeLabel
660 labelType (RtsLabel (RtsInfo _))              = DataLabel
661 labelType (RtsLabel (RtsEntry _))             = CodeLabel
662 labelType (RtsLabel (RtsRetInfo _))           = DataLabel
663 labelType (RtsLabel (RtsRet _))               = CodeLabel
664 labelType (RtsLabel (RtsDataFS _))            = DataLabel
665 labelType (RtsLabel (RtsCodeFS _))            = CodeLabel
666 labelType (RtsLabel (RtsInfoFS _))            = DataLabel
667 labelType (RtsLabel (RtsEntryFS _))           = CodeLabel
668 labelType (RtsLabel (RtsRetInfoFS _))         = DataLabel
669 labelType (RtsLabel (RtsRetFS _))             = CodeLabel
670 labelType (RtsLabel (RtsApFast _))            = CodeLabel
671 labelType (CaseLabel _ CaseReturnInfo)        = DataLabel
672 labelType (CaseLabel _ _)                     = CodeLabel
673 labelType (ModuleInitLabel _ _)               = CodeLabel
674 labelType (PlainModuleInitLabel _)            = CodeLabel
675 labelType (ModuleInitTableLabel _)            = DataLabel
676 labelType (LargeSRTLabel _)                   = DataLabel
677 labelType (LargeBitmapLabel _)                = DataLabel
678 labelType (ForeignLabel _ _ _ IsFunction) = CodeLabel
679 labelType (IdLabel _ _ info) = idInfoLabelType info
680 labelType _                = DataLabel
681
682 idInfoLabelType info =
683   case info of
684     InfoTable     -> DataLabel
685     Closure       -> GcPtrLabel
686     ConInfoTable  -> DataLabel
687     StaticInfoTable -> DataLabel
688     ClosureTable  -> DataLabel
689     RednCounts    -> DataLabel
690     _             -> CodeLabel
691
692
693 -- -----------------------------------------------------------------------------
694 -- Does a CLabel need dynamic linkage?
695
696 -- When referring to data in code, we need to know whether
697 -- that data resides in a DLL or not. [Win32 only.]
698 -- @labelDynamic@ returns @True@ if the label is located
699 -- in a DLL, be it a data reference or not.
700
701 labelDynamic :: PackageId -> CLabel -> Bool
702 labelDynamic this_pkg lbl =
703   case lbl of
704    RtsLabel _        -> not opt_Static && (this_pkg /= rtsPackageId) -- i.e., is the RTS in a DLL or not?
705    IdLabel n _ k       -> isDllName this_pkg n
706 #if mingw32_TARGET_OS
707    ForeignLabel _ _ d _ -> d
708 #else
709    -- On Mac OS X and on ELF platforms, false positives are OK,
710    -- so we claim that all foreign imports come from dynamic libraries
711    ForeignLabel _ _ _ _ -> True
712 #endif
713    ModuleInitLabel m _    -> not opt_Static && this_pkg /= (modulePackageId m)
714    PlainModuleInitLabel m -> not opt_Static && this_pkg /= (modulePackageId m)
715    ModuleInitTableLabel m -> not opt_Static && this_pkg /= (modulePackageId m)
716    
717    -- Note that DynamicLinkerLabels do NOT require dynamic linking themselves.
718    _                 -> False
719
720 {-
721 OLD?: These GRAN functions are needed for spitting out GRAN_FETCH() at the
722 right places. It is used to detect when the abstractC statement of an
723 CCodeBlock actually contains the code for a slow entry point.  -- HWL
724
725 We need at least @Eq@ for @CLabels@, because we want to avoid
726 duplicate declarations in generating C (see @labelSeenTE@ in
727 @PprAbsC@).
728 -}
729
730 -----------------------------------------------------------------------------
731 -- Printing out CLabels.
732
733 {-
734 Convention:
735
736       <name>_<type>
737
738 where <name> is <Module>_<name> for external names and <unique> for
739 internal names. <type> is one of the following:
740
741          info                   Info table
742          srt                    Static reference table
743          srtd                   Static reference table descriptor
744          entry                  Entry code (function, closure)
745          slow                   Slow entry code (if any)
746          ret                    Direct return address    
747          vtbl                   Vector table
748          <n>_alt                Case alternative (tag n)
749          dflt                   Default case alternative
750          btm                    Large bitmap vector
751          closure                Static closure
752          con_entry              Dynamic Constructor entry code
753          con_info               Dynamic Constructor info table
754          static_entry           Static Constructor entry code
755          static_info            Static Constructor info table
756          sel_info               Selector info table
757          sel_entry              Selector entry code
758          cc                     Cost centre
759          ccs                    Cost centre stack
760
761 Many of these distinctions are only for documentation reasons.  For
762 example, _ret is only distinguished from _entry to make it easy to
763 tell whether a code fragment is a return point or a closure/function
764 entry.
765 -}
766
767 instance Outputable CLabel where
768   ppr = pprCLabel
769
770 pprCLabel :: CLabel -> SDoc
771
772 #if ! OMIT_NATIVE_CODEGEN
773 pprCLabel (AsmTempLabel u)
774   =  getPprStyle $ \ sty ->
775      if asmStyle sty then 
776         ptext asmTempLabelPrefix <> pprUnique u
777      else
778         char '_' <> pprUnique u
779
780 pprCLabel (DynamicLinkerLabel info lbl)
781    = pprDynamicLinkerAsmLabel info lbl
782    
783 pprCLabel PicBaseLabel
784    = ptext (sLit "1b")
785    
786 pprCLabel (DeadStripPreventer lbl)
787    = pprCLabel lbl <> ptext (sLit "_dsp")
788 #endif
789
790 pprCLabel lbl = 
791 #if ! OMIT_NATIVE_CODEGEN
792     getPprStyle $ \ sty ->
793     if asmStyle sty then 
794         maybe_underscore (pprAsmCLbl lbl)
795     else
796 #endif
797        pprCLbl lbl
798
799 maybe_underscore doc
800   | underscorePrefix = pp_cSEP <> doc
801   | otherwise        = doc
802
803 #ifdef mingw32_TARGET_OS
804 -- In asm mode, we need to put the suffix on a stdcall ForeignLabel.
805 -- (The C compiler does this itself).
806 pprAsmCLbl (ForeignLabel fs (Just sz) _ _)
807    = ftext fs <> char '@' <> int sz
808 #endif
809 pprAsmCLbl lbl
810    = pprCLbl lbl
811
812 pprCLbl (StringLitLabel u)
813   = pprUnique u <> ptext (sLit "_str")
814
815 pprCLbl (CaseLabel u CaseReturnPt)
816   = hcat [pprUnique u, ptext (sLit "_ret")]
817 pprCLbl (CaseLabel u CaseReturnInfo)
818   = hcat [pprUnique u, ptext (sLit "_info")]
819 pprCLbl (CaseLabel u (CaseAlt tag))
820   = hcat [pprUnique u, pp_cSEP, int tag, ptext (sLit "_alt")]
821 pprCLbl (CaseLabel u CaseDefault)
822   = hcat [pprUnique u, ptext (sLit "_dflt")]
823
824 pprCLbl (LargeSRTLabel u)  = pprUnique u <> pp_cSEP <> ptext (sLit "srtd")
825 pprCLbl (LargeBitmapLabel u)  = text "b" <> pprUnique u <> pp_cSEP <> ptext (sLit "btm")
826 -- Some bitsmaps for tuple constructors have a numeric tag (e.g. '7')
827 -- until that gets resolved we'll just force them to start
828 -- with a letter so the label will be legal assmbly code.
829         
830
831 pprCLbl (RtsLabel (RtsCode str))   = ptext str
832 pprCLbl (RtsLabel (RtsData str))   = ptext str
833 pprCLbl (RtsLabel (RtsGcPtr str))  = ptext str
834 pprCLbl (RtsLabel (RtsCodeFS str)) = ftext str
835 pprCLbl (RtsLabel (RtsDataFS str)) = ftext str
836
837 pprCLbl (RtsLabel (RtsApFast str)) = ptext str <> ptext (sLit "_fast")
838
839 pprCLbl (RtsLabel (RtsSelectorInfoTable upd_reqd offset))
840   = hcat [ptext (sLit "stg_sel_"), text (show offset),
841                 ptext (if upd_reqd 
842                         then (sLit "_upd_info") 
843                         else (sLit "_noupd_info"))
844         ]
845
846 pprCLbl (RtsLabel (RtsSelectorEntry upd_reqd offset))
847   = hcat [ptext (sLit "stg_sel_"), text (show offset),
848                 ptext (if upd_reqd 
849                         then (sLit "_upd_entry") 
850                         else (sLit "_noupd_entry"))
851         ]
852
853 pprCLbl (RtsLabel (RtsApInfoTable upd_reqd arity))
854   = hcat [ptext (sLit "stg_ap_"), text (show arity),
855                 ptext (if upd_reqd 
856                         then (sLit "_upd_info") 
857                         else (sLit "_noupd_info"))
858         ]
859
860 pprCLbl (RtsLabel (RtsApEntry upd_reqd arity))
861   = hcat [ptext (sLit "stg_ap_"), text (show arity),
862                 ptext (if upd_reqd 
863                         then (sLit "_upd_entry") 
864                         else (sLit "_noupd_entry"))
865         ]
866
867 pprCLbl (RtsLabel (RtsInfo fs))
868   = ptext fs <> ptext (sLit "_info")
869
870 pprCLbl (RtsLabel (RtsEntry fs))
871   = ptext fs <> ptext (sLit "_entry")
872
873 pprCLbl (RtsLabel (RtsRetInfo fs))
874   = ptext fs <> ptext (sLit "_info")
875
876 pprCLbl (RtsLabel (RtsRet fs))
877   = ptext fs <> ptext (sLit "_ret")
878
879 pprCLbl (RtsLabel (RtsInfoFS fs))
880   = ftext fs <> ptext (sLit "_info")
881
882 pprCLbl (RtsLabel (RtsEntryFS fs))
883   = ftext fs <> ptext (sLit "_entry")
884
885 pprCLbl (RtsLabel (RtsRetInfoFS fs))
886   = ftext fs <> ptext (sLit "_info")
887
888 pprCLbl (RtsLabel (RtsRetFS fs))
889   = ftext fs <> ptext (sLit "_ret")
890
891 pprCLbl (RtsLabel (RtsPrimOp primop)) 
892   = ppr primop <> ptext (sLit "_fast")
893
894 pprCLbl (RtsLabel (RtsSlowTickyCtr pat)) 
895   = ptext (sLit "SLOW_CALL_") <> text pat <> ptext (sLit "_ctr")
896
897 pprCLbl ModuleRegdLabel
898   = ptext (sLit "_module_registered")
899
900 pprCLbl (ForeignLabel str _ _ _)
901   = ftext str
902
903 pprCLbl (IdLabel name cafs flavor) = ppr name <> ppIdFlavor flavor
904
905 pprCLbl (CC_Label cc)           = ppr cc
906 pprCLbl (CCS_Label ccs)         = ppr ccs
907
908 pprCLbl (ModuleInitLabel mod way)
909    = ptext (sLit "__stginit_") <> ppr mod
910         <> char '_' <> text way
911 pprCLbl (PlainModuleInitLabel mod)
912    = ptext (sLit "__stginit_") <> ppr mod
913 pprCLbl (ModuleInitTableLabel mod)
914    = ptext (sLit "__stginittable_") <> ppr mod
915
916 pprCLbl (HpcTicksLabel mod)
917   = ptext (sLit "_hpc_tickboxes_")  <> ppr mod <> ptext (sLit "_hpc")
918
919 pprCLbl HpcModuleNameLabel
920   = ptext (sLit "_hpc_module_name_str")
921
922 ppIdFlavor :: IdLabelInfo -> SDoc
923 ppIdFlavor x = pp_cSEP <>
924                (case x of
925                        Closure          -> ptext (sLit "closure")
926                        SRT              -> ptext (sLit "srt")
927                        InfoTable        -> ptext (sLit "info")
928                        Entry            -> ptext (sLit "entry")
929                        Slow             -> ptext (sLit "slow")
930                        RednCounts       -> ptext (sLit "ct")
931                        ConEntry         -> ptext (sLit "con_entry")
932                        ConInfoTable     -> ptext (sLit "con_info")
933                        StaticConEntry   -> ptext (sLit "static_entry")
934                        StaticInfoTable  -> ptext (sLit "static_info")
935                        ClosureTable     -> ptext (sLit "closure_tbl")
936                       )
937
938
939 pp_cSEP = char '_'
940
941 -- -----------------------------------------------------------------------------
942 -- Machine-dependent knowledge about labels.
943
944 underscorePrefix :: Bool   -- leading underscore on assembler labels?
945 underscorePrefix = (cLeadingUnderscore == "YES")
946
947 asmTempLabelPrefix :: LitString  -- for formatting labels
948 asmTempLabelPrefix =
949 #if alpha_TARGET_OS
950      {- The alpha assembler likes temporary labels to look like $L123
951         instead of L123.  (Don't toss the L, because then Lf28
952         turns into $f28.)
953      -}
954      (sLit "$")
955 #elif darwin_TARGET_OS
956      (sLit "L")
957 #else
958      (sLit ".L")
959 #endif
960
961 pprDynamicLinkerAsmLabel :: DynamicLinkerLabelInfo -> CLabel -> SDoc
962
963 #if x86_64_TARGET_ARCH && darwin_TARGET_OS
964 pprDynamicLinkerAsmLabel GotSymbolPtr lbl
965   = pprCLabel lbl <> text "@GOTPCREL"
966 pprDynamicLinkerAsmLabel GotSymbolOffset lbl
967   = pprCLabel lbl
968 pprDynamicLinkerAsmLabel _ _
969   = panic "pprDynamicLinkerAsmLabel"
970 #elif darwin_TARGET_OS
971 pprDynamicLinkerAsmLabel CodeStub lbl
972   = char 'L' <> pprCLabel lbl <> text "$stub"
973 pprDynamicLinkerAsmLabel SymbolPtr lbl
974   = char 'L' <> pprCLabel lbl <> text "$non_lazy_ptr"
975 pprDynamicLinkerAsmLabel _ _
976   = panic "pprDynamicLinkerAsmLabel"
977 #elif powerpc_TARGET_ARCH && linux_TARGET_OS
978 pprDynamicLinkerAsmLabel CodeStub lbl
979   = pprCLabel lbl <> text "@plt"
980 pprDynamicLinkerAsmLabel SymbolPtr lbl
981   = text ".LC_" <> pprCLabel lbl
982 pprDynamicLinkerAsmLabel _ _
983   = panic "pprDynamicLinkerAsmLabel"
984 #elif x86_64_TARGET_ARCH && linux_TARGET_OS
985 pprDynamicLinkerAsmLabel CodeStub lbl
986   = pprCLabel lbl <> text "@plt"
987 pprDynamicLinkerAsmLabel GotSymbolPtr lbl
988   = pprCLabel lbl <> text "@gotpcrel"
989 pprDynamicLinkerAsmLabel GotSymbolOffset lbl
990   = pprCLabel lbl
991 pprDynamicLinkerAsmLabel SymbolPtr lbl
992   = text ".LC_" <> pprCLabel lbl
993 #elif linux_TARGET_OS
994 pprDynamicLinkerAsmLabel CodeStub lbl
995   = pprCLabel lbl <> text "@plt"
996 pprDynamicLinkerAsmLabel SymbolPtr lbl
997   = text ".LC_" <> pprCLabel lbl
998 pprDynamicLinkerAsmLabel GotSymbolPtr lbl
999   = pprCLabel lbl <> text "@got"
1000 pprDynamicLinkerAsmLabel GotSymbolOffset lbl
1001   = pprCLabel lbl <> text "@gotoff"
1002 #elif mingw32_TARGET_OS
1003 pprDynamicLinkerAsmLabel SymbolPtr lbl
1004   = text "__imp_" <> pprCLabel lbl
1005 pprDynamicLinkerAsmLabel _ _
1006   = panic "pprDynamicLinkerAsmLabel"
1007 #else
1008 pprDynamicLinkerAsmLabel _ _
1009   = panic "pprDynamicLinkerAsmLabel"
1010 #endif