mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	32-bit x86 MSVC-style exceptions are functionaly similar to 64-bit, but they take no arguments. Instead, they implicitly use the value of EBP passed in by the caller as a pointer to the parent's frame. In LLVM, we can represent this as llvm.frameaddress(1), and feed that into all of our calls to llvm.framerecover. The next steps are: - Add an alloca to the fs:00 linked list of handlers - Add something like llvm.sjlj.lsda or generalize it to store in the alloca - Move state number calculation to WinEHPrepare, arrange for FunctionLoweringInfo to call it - Use the state numbers to insert explicit loads and stores in the IR git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236172 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			91 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===- LibCallSemantics.cpp - Describe library semantics ------------------===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // This file implements interfaces that can be used to describe language
 | |
| // specific runtime library interfaces (e.g. libc, libm, etc) to LLVM
 | |
| // optimizers.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "llvm/Analysis/LibCallSemantics.h"
 | |
| #include "llvm/ADT/StringMap.h"
 | |
| #include "llvm/ADT/StringSwitch.h"
 | |
| #include "llvm/IR/Function.h"
 | |
| using namespace llvm;
 | |
| 
 | |
| /// This impl pointer in ~LibCallInfo is actually a StringMap.  This
 | |
| /// helper does the cast.
 | |
| static StringMap<const LibCallFunctionInfo*> *getMap(void *Ptr) {
 | |
|   return static_cast<StringMap<const LibCallFunctionInfo*> *>(Ptr);
 | |
| }
 | |
| 
 | |
| LibCallInfo::~LibCallInfo() {
 | |
|   delete getMap(Impl);
 | |
| }
 | |
| 
 | |
| const LibCallLocationInfo &LibCallInfo::getLocationInfo(unsigned LocID) const {
 | |
|   // Get location info on the first call.
 | |
|   if (NumLocations == 0)
 | |
|     NumLocations = getLocationInfo(Locations);
 | |
|   
 | |
|   assert(LocID < NumLocations && "Invalid location ID!");
 | |
|   return Locations[LocID];
 | |
| }
 | |
| 
 | |
| 
 | |
| /// Return the LibCallFunctionInfo object corresponding to
 | |
| /// the specified function if we have it.  If not, return null.
 | |
| const LibCallFunctionInfo *
 | |
| LibCallInfo::getFunctionInfo(const Function *F) const {
 | |
|   StringMap<const LibCallFunctionInfo*> *Map = getMap(Impl);
 | |
|   
 | |
|   /// If this is the first time we are querying for this info, lazily construct
 | |
|   /// the StringMap to index it.
 | |
|   if (!Map) {
 | |
|     Impl = Map = new StringMap<const LibCallFunctionInfo*>();
 | |
|     
 | |
|     const LibCallFunctionInfo *Array = getFunctionInfoArray();
 | |
|     if (!Array) return nullptr;
 | |
|     
 | |
|     // We now have the array of entries.  Populate the StringMap.
 | |
|     for (unsigned i = 0; Array[i].Name; ++i)
 | |
|       (*Map)[Array[i].Name] = Array+i;
 | |
|   }
 | |
|   
 | |
|   // Look up this function in the string map.
 | |
|   return Map->lookup(F->getName());
 | |
| }
 | |
| 
 | |
| /// See if the given exception handling personality function is one that we
 | |
| /// understand.  If so, return a description of it; otherwise return Unknown.
 | |
| EHPersonality llvm::classifyEHPersonality(const Value *Pers) {
 | |
|   const Function *F = dyn_cast<Function>(Pers->stripPointerCasts());
 | |
|   if (!F)
 | |
|     return EHPersonality::Unknown;
 | |
|   return StringSwitch<EHPersonality>(F->getName())
 | |
|     .Case("__gnat_eh_personality", EHPersonality::GNU_Ada)
 | |
|     .Case("__gxx_personality_v0",  EHPersonality::GNU_CXX)
 | |
|     .Case("__gcc_personality_v0",  EHPersonality::GNU_C)
 | |
|     .Case("__objc_personality_v0", EHPersonality::GNU_ObjC)
 | |
|     .Case("_except_handler3",      EHPersonality::MSVC_X86SEH)
 | |
|     .Case("_except_handler4",      EHPersonality::MSVC_X86SEH)
 | |
|     .Case("__C_specific_handler",  EHPersonality::MSVC_Win64SEH)
 | |
|     .Case("__CxxFrameHandler3",    EHPersonality::MSVC_CXX)
 | |
|     .Default(EHPersonality::Unknown);
 | |
| }
 | |
| 
 | |
| bool llvm::canSimplifyInvokeNoUnwind(const InvokeInst *II) {
 | |
|   const LandingPadInst *LP = II->getLandingPadInst();
 | |
|   EHPersonality Personality = classifyEHPersonality(LP->getPersonalityFn());
 | |
|   // We can't simplify any invokes to nounwind functions if the personality
 | |
|   // function wants to catch asynch exceptions.  The nounwind attribute only
 | |
|   // implies that the function does not throw synchronous exceptions.
 | |
|   return !isAsynchronousEHPersonality(Personality);
 | |
| }
 |