8

यह (AFAIK) this general topic के भीतर एक विशिष्ट प्रश्न है।मैं 32-बिट विभाजन निर्देश के साथ 64-बिट विभाजन कैसे कर सकता हूं?

यहाँ की स्थिति है:

मैं एक एम्बेडेड सिस्टम (एक वीडियो गेम कंसोल) एक 32-बिट RISC माइक्रोकंट्रोलर के आधार पर (NEC के V810 का एक प्रकार) है। मैं एक निश्चित बिंदु गणित पुस्तकालय लिखना चाहता हूँ। मैंने this article पढ़ा है, लेकिन साथ में स्रोत कोड 386 असेंबली में लिखा गया है, इसलिए यह न तो सीधे उपयोग करने योग्य और न ही आसानी से संशोधित है।

वी 810 में पूर्णांक पूर्णांक/विभाजित है, लेकिन मैं उपर्युक्त आलेख में उल्लिखित 18.14 प्रारूप का उपयोग करना चाहता हूं। इसके लिए 32-बिट int द्वारा 64-बिट int को विभाजित करने की आवश्यकता होती है, और V810 केवल 32-बिट/32-बिट डिवीजन (हस्ताक्षरित या हस्ताक्षरित) करता है (जो 32-बिट मात्रात्मक और 32-बिट शेष उत्पन्न करता है)।

तो, मेरा सवाल है: मैं 32-बिट/32-बिट एक के साथ 64-बिट/32-बिट विभाजन को अनुकरण कैसे करूं (लाभांश के पूर्व-स्थानांतरण के लिए अनुमति देने के लिए)? या, किसी अन्य तरीके से समस्या को देखने के लिए, मानक 32-बिट अंकगणितीय/तर्क परिचालनों का उपयोग करके किसी अन्य द्वारा 18.14 निश्चित-बिंदु को विभाजित करने का सबसे अच्छा तरीका क्या है? ("सबसे अच्छा" अर्थ सबसे तेज़, छोटा, या दोनों)।

बीजगणित, (वी 810) असेंबली, और छद्म कोड सभी ठीक हैं। मैं सी

से कोड को कॉल कर रहा हूं अग्रिम धन्यवाद!

संपादित करें: किसी भी तरह से मैंने this question को याद किया ... हालांकि, इसे अभी भी सुपर-कुशल होने के लिए कुछ संशोधन की आवश्यकता होगी (इसे v810 द्वारा प्रदान किए गए फ़्लोटिंग-पॉइंट डिव से तेज होना चाहिए, हालांकि यह पहले से ही हो सकता है .. ।), इसलिए प्रतिष्ठा बिंदुओं के बदले में मेरे लिए अपना काम करने में संकोच न करें;) (और निश्चित रूप से मेरे पुस्तकालय दस्तावेज में क्रेडिट)।

+0

[32/16-बिट विभाजन के साथ प्रोसेसर पर 64/32-बिट विभाजन] (https://stackoverflow.com/q/ 4771823/995714) –

उत्तर

5

जीसीसी के पास कई प्रोसेसर के लिए ऐसा दिनचर्या है, जिसका नाम _divdi3 है (आमतौर पर एक सामान्य divmod कॉल का उपयोग करके लागू किया जाता है)। Here's one। कुछ यूनिक्स कर्नेल में भी एक कार्यान्वयन है, उदा। FreeBSD

+0

यह वही है जो मुझे चाहिए। प्रासंगिक कोड से जोड़ने के लिए धन्यवाद! बीटीडब्ल्यू, मैं जीसीसी का उपयोग कर रहा हूं, लेकिन मैं न्यूलिब का उपयोग कर रहा हूं, जिसमें यह सामान शामिल नहीं है। – RunnerPack

0

अपने लाभांश अहस्ताक्षरित 64 बिट्स है, तो आपके भाजक अहस्ताक्षरित 32 बिट है, वास्तुकला (x86) i386 है, div विधानसभा अनुदेश कुछ तैयारी में आपकी मदद कर सकते हैं:

#include <stdint.h> 
/* Returns *a % b, and sets *a = *a_old/b; */ 
uint32_t UInt64DivAndGetMod(uint64_t *a, uint32_t b) { 
#ifdef __i386__ /* u64/u32 division with little i386 machine code. */ 
    uint32_t upper = ((uint32_t*)a)[1], r; 
    ((uint32_t*)a)[1] = 0; 
    if (upper >= b) { 
    ((uint32_t*)a)[1] = upper/b; 
    upper %= b; 
    } 
    __asm__("divl %2" : "=a" (((uint32_t*)a)[0]), "=d" (r) : 
     "rm" (b), "0" (((uint32_t*)a)[0]), "1" (upper)); 
    return r; 
#else 
    const uint64_t q = *a/b; /* Calls __udivdi3 in libgcc. */ 
    const uint32_t r = *a - b * q; /* `r = *a % b' would use __umoddi3. */ 
    *a = q; 
    return r; 
#endif 
} 

साथ उपरोक्त पंक्ति हैं __udivdi3 आपके लिए संकलित नहीं है, लिनक्स कर्नेल से __div64_32 फ़ंक्शन का उपयोग करें: https://github.com/torvalds/linux/blob/master/lib/div64.c